WPF'de bir bağımlılık özelliği ile ekli bir özellik arasındaki fark nedir?


Yanıtlar:


21

Öz

Konuyla ilgili çok az veya hiç belge bulmadığım için, kaynak kodun etrafından dolaşmak biraz zaman aldı , ama işte bir cevap.

Bir bağımlılık özelliğini normal ve ekli bir özellik olarak kaydetmek arasında, "felsefi" bir özellik dışında bir fark vardır ( normal özelliklerin bildirim türü ve türetme türleri tarafından kullanılması amaçlanmıştır, ekli özelliklerin şu şekilde kullanılması amaçlanmıştır: rastgele DependencyObject örneklerdeki uzantılar ). "Felsefi", çünkü @MarqueIV'in @ ReedCopsey'in cevabına yaptığı yorumda fark ettiği gibi, normal özellikler rastgele DependencyObjectörneklerle de kullanılabilir .

Dahası, ekli özelliğin "bağımlılık özelliği türü" olduğunu belirten diğer yanıtlara katılmıyorum, çünkü yanıltıcıdır - bağımlılık özelliklerinin "türü" yoktur. Çerçeve, mülkün ekli olarak kaydedilip kaydedilmediğini umursamıyor - belirlemek bile mümkün değil (bu bilginin kayda geçirilmemesi anlamında, çünkü alakasız). Aslında, tüm özellikler iliştirilmiş mülklermiş gibi kaydedilir, ancak normal olanlar durumunda davranışlarını biraz değiştiren bazı ek şeyler yapılır.

Kod alıntı

Sizi kaynak kodundan kendi başınıza geçme zahmetinden kurtarmak için, burada olanların özetlenmiş bir versiyonu var.

Meta veriler belirtilmeden bir mülkü kaydederken, arama

DependencyProperty.Register(
    name: "MyProperty",
    propertyType: typeof(object),
    ownerType: typeof(MyClass))

arama ile tam olarak aynı sonucu verir

DependencyProperty.RegisterAttached(
    name: "MyProperty",
    propertyType: typeof(object),
    ownerType: typeof(MyClass))

Ancak, meta verileri belirtirken arama

DependencyProperty.Register(
    name: "MyProperty",
    propertyType: typeof(object),
    ownerType: typeof(MyClass),
    typeMetadata: new FrameworkPropertyMetadata
    {
        CoerceValueCallback = CoerceCallback,
        DefaultValue = "default value",
        PropertyChangedCallback = ChangedCallback
    });

aramaya eşdeğerdir

var property = DependencyProperty.RegisterAttached(
    name: "MyProperty",
    propertyType: typeof(object),
    ownerType: typeof(MyClass),
    defaultMetadata: new PropertyMetadata
    {
        DefaultValue = "default value",
    });
property.OverrideMetadata(
    forType: typeof(MyClass),
    typeMetadata: new FrameworkPropertyMetadata
    {
        CoerceValueCallback = CoerceCallback,
        DefaultValue = "default value",
        PropertyChangedCallback = ChangedCallback
    });

Sonuçlar

Normal ve ekli bağımlılık özellikleri arasındaki temel (ve tek) fark, DependencyProperty.DefaultMetadata özelliği aracılığıyla kullanılabilen varsayılan meta verilerdir . Bu, Açıklamalar bölümünde bile bahsedilmektedir :

Eklenmemiş özellikler için, bu özellik tarafından döndürülen meta veri türü , özellik başlangıçta türetilmiş bir meta veri türüyle kaydedilmiş olsa bile, türetilmiş PropertyMetadata türü türlerine dönüştürülemez . Orijinal muhtemelen türetilmiş meta veri türü dahil olmak üzere orijinal olarak kaydedilmiş meta verileri istiyorsanız, bunun yerine GetMetadata (Tür) öğesini çağırın ve orijinal kayıt türünü bir parametre olarak iletin .

Ekli özellikler için, bu özellik tarafından döndürülen meta verilerin türü, orijinal RegisterAttached kayıt yönteminde verilen türle eşleşecektir .

Bu, sağlanan kodda açıkça görülebilir. Kayıt yöntemlerinde küçük ipuçları da gizlidir, yani RegisterAttachedmetadata parametresi adlandırılır defaultMetadata, oysa Registerbunun için adlandırılır typeMetadata. Ekli özellikler için sağlanan meta veriler varsayılan meta veriler haline gelir. Bununla birlikte, normal özellikler durumunda, varsayılan meta veriler her zaman PropertyMetadatayalnızca DefaultValueayarlanmış (sağlanan meta verilerden veya otomatik olarak) yeni bir örneğidir . Yalnızca sonraki çağrı OverrideMetadatagerçekten sağlanan meta verileri kullanır.

Sonuçlar

Temel pratik fark, normal mülkler durumunda CoerceValueCallbackve yalnızca sahip türü olarak bildirilen türden türetilen türler için PropertyChangedCallbackgeçerli olması ve ekli mülkler için tüm türler için geçerli olmasıdır . Örneğin bu senaryoda:

var d = new DependencyObject();
d.SetValue(SomeClass.SomeProperty, "some value");

Kayıtlı PropertyChangedCallback adı verilecek mülkiyet iliştirilmiş bir özellik olarak tescil edilmiş ise, ancak denilen olmayacak düzenli özelliği olarak kaydedildi eğer. Aynı şey geçerli CoerceValueCallback.

İkincil bir fark OverrideMetadata, sağlanan türün türetilmesini gerektiren olgudan kaynaklanır DependencyObject. Pratikte, normal özellikleri için sahibi tipi anlamına gelir türetilmelidir gelen DependencyObjectolabilir ekli özellikleri için ise, herhangi bir (statik sınıflar, yapılar, enums, temsilciler, vs. dahil olmak üzere) tipi.

Ek

MarqueIV önerisi @ yanında çeşitli vesilelerle ben düzenli ve ekli özellikleri bunlar kullanılabilecek şekilde farklılık gösterdiğini görüşleri rastlamak ettik XAML . Yani, normal özellikler, ekli özelliklerin gerektirdiği açık ad sözdiziminin tersine örtük ad sözdizimi gerektirir. Bu teknik olarak doğru değildir , ancak pratikte genellikle böyledir. Açıklık için:

<!-- Implicit property name -->
<ns:SomeClass SomeProperty="some value" /> 

<!-- Explicit property name -->
<DependencyObject ns:SomeClass.SomeProperty="some value" />

Gelen saf XAML , bu sözdizimlerinden kullanımını düzenleyen tek kuralları aşağıdaki gibidir:

  • Örtük ad sözdizimi, bir öğede ancak ve ancak bu öğenin temsil ettiği sınıfın bu ada ait bir CLR özelliğine sahip olması durumunda kullanılabilir.
  • Açık ad sözdizimi, ancak ve ancak tam adın ilk bölümü tarafından belirtilen sınıf, tam adın ikinci bölümü ile eşleşen adlarla uygun statik get / set yöntemlerini ( erişimciler olarak adlandırılır ) ortaya çıkarsa ve bu durumda kullanılabilir.

Bu koşulların sağlanması, destek bağımlılığı özelliğinin normal veya ekli olarak kaydedilmiş olup olmadığına bakılmaksızın, karşılık gelen sözdizimini kullanmanıza olanak tanır.

Şimdi, bahsedilen yanlış kanı, öğreticilerin büyük çoğunluğunun (stok Visual Studio kod parçacıklarıyla birlikte) , normal bağımlılık özellikleri için CLR özelliğini ve ekli olanlar için erişimcileri al / ayarlamanızı gerektirdiği gerçeğinden kaynaklanmaktadır . Ancak ikisini de aynı anda kullanmaktan sizi alıkoyan hiçbir şey yoktur, bu da tercih ettiğiniz sözdizimini kullanmanıza izin verir.


71

Ekli özellikler bir tür bağımlılık özelliğidir. Aradaki fark, nasıl kullanıldıklarında.

Ekli bir özellik ile özellik, kullanıldığı sınıfla aynı olmayan bir sınıf üzerinde tanımlanır. Bu genellikle düzen için kullanılır. İyi örnekler Panel.ZIndex veya Grid.Row'dur - bunu bir kontrole uygularsınız (yani: Button), ancak aslında Panel veya Grid'de tanımlanır. Özellik, düğme örneğine "eklenir".

Bu, örneğin bir konteynerin herhangi bir UIelement üzerinde kullanılabilecek özellikler oluşturmasına izin verir.

Uygulama farklılıklarına gelince - temelde özelliği tanımlarken Register ve RegisterAttached arasındaki farkı kullanma meselesidir.


10
Ama fark tam olarak nedir ?! Gördüğüm kadarıyla, eklenemeyen bir özelliği kod aracılığıyla bir başkasına ekleyebilirsiniz (bunun XAML'de engellendiğini düşünüyorum.) Belki de fark budur?
Mark A. Donohoe

5

Ekli özellikler temelde kap öğeleri içindir. Bir ızgaranız ve grid.row'unuz varsa, şimdi bu bir ızgara öğesinin ekli özelliği olarak kabul edilir. Ayrıca bu özelliği texbox, button vb. ızgaraya yerleştirin.

Bağımlılık özelliği, temelde başka bir sınıfa ait olan ve başka bir sınıfta kullanılan nitelik gibidir. örneğin: burada bir dikdörtgene sahip olduğunuz gibi, yükseklik ve genişlik dikdörtgenin normal özellikleridir, ancak Canvass sınıfına ait olduğu için sol ve üst bağımlılık özelliğidir.


-1

Ekli özellikler, özel bir DependencyProperties türüdür. Bu değer hakkında hiçbir şey bilmeyen bir nesneye bir değer eklemenize izin verirler. Bu konsept için iyi bir örnek, yerleşim panelleridir. Her düzen panelinin, alt öğelerini hizalamak için farklı verilere ihtiyacı vardır. Canvas'ın Yukarı ve Sola, DockPanel'in Dock'a vb. İhtiyacı vardır. Kendi düzen panelinizi yazabileceğiniz için liste sonsuzdur. Gördüğünüz gibi, tüm bu özelliklere tüm WPF kontrollerinde sahip olmak mümkün değildir. Çözüm, ekli özelliklerdir. Belirli bir bağlamda başka bir kontrolden gelen verilere ihtiyaç duyan kontrol tarafından tanımlanırlar. Örneğin, bir ana mizanpaj paneli ile hizalanan bir öğe.


-1

Ekli özelliği sınıfın kendisinde tanımlayabileceğinizi veya başka bir sınıfta tanımlayabileceğinizi düşünüyorum. Standart microsoft denetimlerini genişletmek için her zaman ekli özelliği kullanabiliriz. Ancak bağımlılık özelliğini kendi özel kontrolünüzde tanımlarsınız. Örneğin, kontrolünüzü standart bir kontrolden devralabilir ve kendi kontrolünüzde bir bağımlılık özelliği tanımlayabilir ve onu kullanabilirsiniz. Bu, ekli bir özelliği tanımlamaya ve bu ekli özelliği standart denetimde kullanmaya eşdeğerdir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.