Aracılığıyla paylaş


Özel bağımlılık özellikleri

Windows Presentation Foundation (WPF) uygulama geliştiricileri ve bileşen yazarları, özelliklerinin işlevselliğini genişletmek için özel bağımlılık özellikleri oluşturabilir. ortak dil çalışma zamanı (CLR) özelliğinden farklı olarak, bağımlı özellik stil oluşturma, veri bağlama, devralma, animasyonlar ve varsayılan değerler için destek ekler. Background, Widthve Text WPF sınıflarındaki mevcut bağımlılık özelliklerine örnektir. Bu makalede özel bağımlılık özelliklerinin nasıl uygulandığı açıklanır ve performans, kullanılabilirlik ve çok yönlülüğü geliştirmeye yönelik seçenekler sunulur.

Önkoşullar

Bağımlılık özellikleri hakkında temel bilgilere sahip olduğunuz ve Bağımlılık Özelliklerine Genel Bakış'ı okuduğunuz varsayılmaktadır. Bu makaledeki örnekleri takip etmek için Genişletilebilir Uygulama biçimlendirme dili (XAML) hakkında bilgi sahibi olmanız ve WPF uygulamalarının nasıl yazabileceğinizi bilmeniz yardımcı olur.

Bağımlılık özelliği tanımlayıcısı

Bağımlılık özellikleri, Register veya RegisterReadOnly çağrıları aracılığıyla WPF özellik sistemine kaydedilen özelliklerdir. Register yöntemi, bir bağımlılık özelliğinin kayıtlı adını ve özelliklerini tutan bir DependencyProperty örneği döndürür. örneğinibağımlılık özelliği tanımlayıcısı olarak bilinen ve kurala göre olarak adlandırılan statik salt okunur bir alana atayacaksınız. Örneğin, Background özelliğinin tanımlayıcı alanı her zaman BackgroundProperty.

Bağımlılık özelliği tanımlayıcısı, bir özelliği özel alanla yedeklemenin standart deseni yerine özellik değerlerini almak veya ayarlamak için bir yedekleme alanı olarak kullanılır. Özellik sistemi yalnızca tanımlayıcıyı kullanmaz, XAML işlemcileri bunu kullanabilir ve kodunuz (ve muhtemelen dış kod) bağımlılık özelliklerine tanımlayıcıları aracılığıyla erişebilir.

Bağımlılık özellikleri yalnızca DependencyObject türlerinden türetilen sınıflara uygulanabilir. çoğu WPF sınıfı bağımlılık özelliklerini destekler çünkü DependencyObject WPF sınıf hiyerarşisinin köküne yakındır. Bağımlılık özellikleri ve bunları açıklamak için kullanılan terminoloji ve kurallar hakkında daha fazla bilgi için bkz. Bağımlılık özelliklerine genel bakış.

Bağımlılık özelliği kaplamaları

Ekli özellikler olmayan WPF bağımlılık özellikleri, get ve set erişimcileri uygulayan bir CLR sarmalayıcısı tarafından kullanıma sunulur. Özellik sarmalayıcı kullanarak, bağımlılık özelliklerinin tüketicileri diğer CLR özellikleri gibi bağımlılık özelliği değerlerini alabilir veya ayarlayabilir. get ve set erişimcileri, bağımlılık özelliği tanımlayıcısını parametre olarak geçirerek DependencyObject.GetValue ve DependencyObject.SetValue çağrıları aracılığıyla temel alınan özellik sistemiyle etkileşim kurar. Bağımlılık özelliklerinin tüketicileri genellikle doğrudan GetValue veya SetValue çağırmaz, ancak özel bağımlılık özelliği uyguluyorsanız sarmalayıcıda bu yöntemleri kullanırsınız.

Bağımlılık özelliği ne zaman uygulanır?

DependencyObject'den türetilen bir sınıfa özellik uyguladığınızda, DependencyProperty tanımlayıcısı ile özelliğinizi destekleyerek bunu bağımlılık özelliği haline getirirsiniz. Bağımlılık özelliği oluşturmanın yararlı olup olmadığı senaryonuza bağlıdır. Özelliğinizi özel bir alanla yedeklemek bazı senaryolar için yeterli olsa da, özelliğinizin aşağıdaki WPF özelliklerinden birini veya daha fazlasını desteklemesini istiyorsanız bir bağımlılık özelliği uygulamayı göz önünde bulundurun:

  • Bir stil içinde ayarlanabilen özellikler. Daha fazla bilgi için bkz. stiller ve şablonlar.

  • Veri bağlamayı destekleyen özellikler. Veri bağlama bağımlılık özellikleri hakkında daha fazla bilgi için bkz . İki denetimin özelliklerini bağlama

  • Dinamik kaynak başvuruları aracılığıyla ayarlanabilen özellikler. Daha fazla bilgi için bkz. XAML kaynakları.

  • Değerlerini öğe ağacındaki bir üst öğeden otomatik olarak devralan özellikler. Bunun için, CLR erişimi için bir özellik sarmalayıcısı da oluştursanız bile RegisterAttachedkullanarak kaydolmanız gerekir. Daha fazla bilgi için bkz. Özellik değeri kalıtımı.

  • Animasyon yapılabilir özellikler. Daha fazla bilgi için bkz . Animasyona genel bakış

  • Bir özellik değeri değiştiğinde WPF özellik sistemi tarafından bildirim. Değişiklikler, özellik sistemi, ortam, kullanıcı veya stillere göre eylemlerden kaynaklanıyor olabilir. Özelliğiniz özellik meta verilerinde özellik sistemi özellik değerinizin değiştiğini her belirlediği zaman çağrılacak bir geri çağırma yöntemi belirtebilir. İlgili kavram, özellik değeri zorlama kavramıdır. Daha fazla bilgi için bkz. Bağlılık özelliği geri çağırma ve doğrulama.

  • WPF işlemleri tarafından okunan bağımlılık özelliği meta verilerine erişim. Örneğin, özellik meta verilerini kullanarak şunları yapabilirsiniz:

    • Değiştirilen bağımlılık özelliği değerinin düzen sisteminin bir öğe için görselleri yeniden derlemesine neden olup olmayacağını belirtin.

    • Türetilmiş sınıflardaki meta verileri geçersiz kılarak bağımlılık özelliğinin varsayılan değerini ayarlayın.

  • Visual Studio WPF tasarımcısı desteği, örneğin Özellikleri penceresinde özel denetimin özelliklerini düzenleme gibi. Daha fazla bilgi için bkz. Denetim yazmaya genel bakış

Bazı senaryolarda, var olan bir bağımlılık özelliğinin meta verilerini geçersiz kılma, yeni bir bağımlılık özelliği uygulamaktan daha iyi bir seçenektir. Meta veri geçersiz kılmanın pratik olup olmadığı senaryonuza ve bu senaryonun mevcut WPF bağımlılık özellikleri ve sınıflarının uygulanmasına ne kadar yakın olduğuna bağlıdır. Meta verileri mevcut bağımlılık özelliklerinde geçersiz kılma hakkında daha fazla bilgi için bkz. Bağımlılık özelliği meta verileri.

Bağımlılık özelliği oluşturmak için denetim listesi

Bağımlılık özelliği oluşturmak için aşağıdaki adımları izleyin. Adımlardan bazıları tek bir kod satırında birleştirilebilir ve uygulanabilir.

  1. (İsteğe bağlı) Bağımlılık özelliği meta verileri oluşturun.

  2. Özellik adını, sahip türünü, özellik değer türünü ve isteğe bağlı olarak özellik meta verilerini belirterek bağımlılık özelliğini özellik sistemine kaydedin.

  3. Sahip türünde DependencyProperty alanı olarak bir public static readonly tanımlayıcısı tanımlayın. Tanımlayıcı alan adının özellik adı, sonuna Property eki eklenmiş halidir.

  4. Bağımlılık özelliğinin adıyla aynı ada sahip bir CLR sarmalayıcı özelliği tanımlayın. CLR sarmalayıcısında, sarmalayıcıyı destekleyen bağımlılık özelliğiyle bağlanan get ve set erişimcilerini uygulayın.

Özelliği kaydetme

Özelliğinizin bir bağımlılık özelliği olması için özelliği özellik sistemine kaydetmeniz gerekir. Özelliğinizi kaydetmek için sınıfınızın gövdesinden, ancak üye tanımlarının dışından Register yöntemini çağırın. Register yöntemi, özellik sistemi API'sini çağırırken kullanacağınız benzersiz bir bağımlılık özellik tanımlayıcısı döndürür. Register çağrısının üye tanımları dışında yapılmasının nedeni, dönüş değerini public static readonlytüründe bir DependencyProperty alanına atamanızdır. Sınıfınızda oluşturacağınız bu alan, bağımlılık özelliğinizin tanımlayıcısıdır. Aşağıdaki örnekte, Register bağımsız değişkenlerinden ilki AquariumGraphicbağımlılık özelliğini adlandırmaktadır.

// Register a dependency property with the specified property name,
// property type, owner type, and property metadata. Store the dependency
// property identifier as a public static readonly member of the class.
public static readonly DependencyProperty AquariumGraphicProperty =
    DependencyProperty.Register(
      name: "AquariumGraphic",
      propertyType: typeof(Uri),
      ownerType: typeof(Aquarium),
      typeMetadata: new FrameworkPropertyMetadata(
          defaultValue: new Uri("http://www.contoso.com/aquarium-graphic.jpg"),
          flags: FrameworkPropertyMetadataOptions.AffectsRender,
          propertyChangedCallback: new PropertyChangedCallback(OnUriChanged))
    );
' Register a dependency property with the specified property name,
' property type, owner type, and property metadata. Store the dependency
' property identifier as a public static readonly member of the class.
Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty =
    DependencyProperty.Register(
        name:="AquariumGraphic",
        propertyType:=GetType(Uri),
        ownerType:=GetType(Aquarium),
        typeMetadata:=New FrameworkPropertyMetadata(
            defaultValue:=New Uri("http://www.contoso.com/aquarium-graphic.jpg"),
            flags:=FrameworkPropertyMetadataOptions.AffectsRender,
            propertyChangedCallback:=New PropertyChangedCallback(AddressOf OnUriChanged)))

Uyarı

Sınıf gövdesinde bağımlılık özelliğini tanımlamak tipik bir uygulamadır, ancak sınıf statik oluşturucusunda bir bağımlılık özelliği tanımlamak da mümkündür. Bağımlılık özelliğini başlatmak için birden fazla kod satırına ihtiyacınız varsa bu yaklaşım mantıklı olabilir.

Bağımlılık özelliği adlandırma

Bağımlılık özellikleri için oluşturulan adlandırma kuralı, özellik sisteminin normal davranışı için zorunludur. Oluşturduğunuz tanımlayıcı alanının adı, Propertysonekiyle özelliğin kayıtlı adı olmalıdır.

Bağımlılık özellik adı, kayıt sınıfında benzersiz olmalıdır. Bir temel tür aracılığıyla devralınan bağımlılık özellikleri zaten kaydedilmiş ve türetilmiş bir tür tarafından kaydedilemez. Ancak, sınıfınızı bağımlılık özelliğinin sahibi olarak tanımlayarak, sınıfınızın devralmadığı bir tür de dahil olmak üzere farklı bir tür tarafından kaydedilmiş bir bağımlılık özelliğini kullanabilirsiniz. Sahip olarak sınıf ekleme hakkında daha fazla bilgi için bkz.Bağımlılık özelliği meta verileri.

Özellik sarmalayıcıyı uygulama

Kural gereği, sarmalayıcı özelliğinin adı, bağımlılık özelliği adı olan Register çağrısının ilk parametresiyle aynı olmalıdır. Sarmalayıcı uygulamanız GetValue erişimcisinde get çağırır ve SetValue erişimcisinde set (okuma-yazma özellikleri için). Aşağıdaki örnek, kayıt çağrısı ve tanımlayıcı alan bildiriminin ardından bir kapsayıcı göstermektedir. WPF sınıflarında tüm genel bağımlılık özellikleri benzer bir sarmalayıcı modeli kullanır.

// Register a dependency property with the specified property name,
// property type, owner type, and property metadata. Store the dependency
// property identifier as a public static readonly member of the class.
public static readonly DependencyProperty AquariumGraphicProperty =
    DependencyProperty.Register(
      name: "AquariumGraphic",
      propertyType: typeof(Uri),
      ownerType: typeof(Aquarium),
      typeMetadata: new FrameworkPropertyMetadata(
          defaultValue: new Uri("http://www.contoso.com/aquarium-graphic.jpg"),
          flags: FrameworkPropertyMetadataOptions.AffectsRender,
          propertyChangedCallback: new PropertyChangedCallback(OnUriChanged))
    );

// Declare a read-write property wrapper.
public Uri AquariumGraphic
{
    get => (Uri)GetValue(AquariumGraphicProperty);
    set => SetValue(AquariumGraphicProperty, value);
}
' Register a dependency property with the specified property name,
' property type, owner type, and property metadata. Store the dependency
' property identifier as a public static readonly member of the class.
Public Shared ReadOnly AquariumGraphicProperty As DependencyProperty =
    DependencyProperty.Register(
        name:="AquariumGraphic",
        propertyType:=GetType(Uri),
        ownerType:=GetType(Aquarium),
        typeMetadata:=New FrameworkPropertyMetadata(
            defaultValue:=New Uri("http://www.contoso.com/aquarium-graphic.jpg"),
            flags:=FrameworkPropertyMetadataOptions.AffectsRender,
            propertyChangedCallback:=New PropertyChangedCallback(AddressOf OnUriChanged)))

' Declare a read-write property wrapper.
Public Property AquariumGraphic As Uri
    Get
        Return CType(GetValue(AquariumGraphicProperty), Uri)
    End Get
    Set
        SetValue(AquariumGraphicProperty, Value)
    End Set
End Property

Nadir durumlar dışında sarmalayıcı uygulamanız yalnızca GetValue ve SetValue kodu içermelidir. Bunun arkasındaki nedenler için bkz. Özel bağımlılık özellikleri için etkileri.

Özelliğiniz yerleşik adlandırma kurallarına uymuyorsa şu sorunlarla karşılaşabilirsiniz:

  • Stillerin ve şablonların bazı yönleri çalışmaz.

  • Çoğu araç ve tasarımcı, XAML'yi düzgün bir şekilde seri hale getirmek ve özellik başına tasarımcı ortamı yardımı sağlamak için adlandırma kurallarına güvenir.

  • WPF XAML yükleyicisinin geçerli uygulaması sarmalayıcıları tamamen atlar ve öznitelik değerlerini işlemek için adlandırma kuralına dayanır. Daha fazla bilgi için bkz. XAML yükleme ve bağımlılık özellikleri.

Bağımlılık özelliği meta verileri

Bağımlılık özelliğini kaydettiğinizde, özellik sistemi özellik özelliklerini depolamak için bir meta veri nesnesi oluşturur. Register yönteminin aşırı yüklemeleri, kayıt sırasında özellik meta verilerini belirtmenize olanak tanır, örneğin Register(String, Type, Type, PropertyMetadata). Özellik meta verilerinin yaygın bir kullanımı, bağımlılık özelliği kullanan yeni örnekler için özel bir varsayılan değer uygulamaktır. Özellik meta verilerini sağlamazsanız, özellik sistemi bağımlılık özelliği özelliklerinin çoğuna varsayılan değerler atar.

FrameworkElementtüretilmiş bir sınıfta bağımlılık özelliği oluşturuyorsanız, temel sınıfı FrameworkPropertyMetadatayerine daha özel meta veri sınıfı PropertyMetadata kullanabilirsiniz. Çeşitli FrameworkPropertyMetadata oluşturucu imzaları, meta veri özelliklerinin farklı birleşimlerini belirtmenize olanak tanır. Yalnızca bir varsayılan değer belirtmek istiyorsanız, FrameworkPropertyMetadata(Object) kullanın ve varsayılan değeri Object parametresine geçirin. Değer türünün propertyType çağrısında belirtilen Register ile eşleştiğinden emin olun.

Bazı FrameworkPropertyMetadata aşırı yüklemeleri, özelliğiniz için meta veri seçeneği bayrakları belirtmenize olanak tanır. Özellik sistemi bu bayrakları ayrık özelliklere dönüştürür ve bayrak değerleri düzen altyapısı gibi WPF işlemleri tarafından kullanılır.

Meta veri bayraklarını ayarlama

Meta veri bayraklarını ayarlarken aşağıdakileri göz önünde bulundurun:

  • Özellik değeriniz (veya bu değere yapılan değişiklikler) düzen sisteminin bir UI öğesini nasıl işleyeceğini etkiliyorsa, aşağıdaki bayraklardan birini veya daha fazlasını ayarlayın:

    • AffectsMeasure, özellik değerindeki bir değişikliğin kullanıcı arabirimi işlemede, özellikle de üst öğesindeki bir nesnenin kapladığı alanda değişiklik gerektirdiğini gösterir. Örneğin, bir Width özelliği için bu meta veri bayrağını ayarlayın.

    • AffectsArrange, özellik değerindeki bir değişikliğin kullanıcı arabirimi işlemede, özellikle de bir nesnenin üst öğesindeki konumunda bir değişiklik gerektirdiğini gösterir. Genellikle nesnenin boyutu da değişmez. Örneğin, bir Alignment özelliği için bu meta veri bayrağını ayarlayın.

    • AffectsRender, düzen ve ölçüyü etkilemeyen, ancak yine de başka bir işleme gerektiren bir değişiklik olduğunu gösterir. Örneğin, bir Background özelliği veya öğenin rengini etkileyen başka bir özellik için bu bayrağı ayarlayın.

    Bu bayrakları, özellik sistemi (veya düzen) geri çağırmalarında geçersiz kılma uygulamalarınızda girdi olarak da kullanabilirsiniz. Örneğin, bir özelliğin değer değişikliğini bildirdiğinde ve meta verilerde OnPropertyChanged ayarlandığında, InvalidateArrange'i çağırmak için bir AffectsArrange geri çağırma kullanabilirsiniz.

  • Bazı özellikler üst öğelerinin işleme özelliklerini başka şekillerde etkiler. Örneğin, MinOrphanLines özelliğindeki değişiklikler bir akış belgesinin genel işlemesini değiştirebilir. Ebeveyn eylemleri kendi özelliklerinizde sinyal etmek için AffectsParentArrange veya AffectsParentMeasure kullanın.

  • Varsayılan olarak, bağımlılık özellikleri veri bağlamayı destekler. Ancak, IsDataBindingAllowed kullanarak gerçekçi bir senaryo olmadığında veya büyük nesnelerde olduğu gibi veri bağlama performansının sorunlu olduğu durumlarda veri bağlamayı devre dışı bırakabilirsiniz.

  • Bağımlılık özellikleri için varsayılan veri bağlama moduOneWayolsa da, belirli bir bağlamanın bağlama modunu TwoWayolarak değiştirebilirsiniz. Daha fazla bilgi için bağlama yönübölümüne bakın. Bağımlılık özelliği yazarı olarak, iki yönlü bağlamayı varsayılan mod yapmayı bile seçebilirsiniz. İki yönlü veri bağlama kullanan mevcut bağımlılık özelliğine örnek olarak MenuItem.IsSubmenuOpen, diğer özelliklere ve yöntem çağrılarına dayalı bir duruma sahiptir. IsSubmenuOpen senaryosu, ayar mantığıyla MenuItem'in kompozisyonu varsayılan tema stiliyle etkileşim kurar. TextBox.Text, varsayılan olarak iki yönlü bağlama kullanan başka bir WPF bağımlılık özelliğidir.

  • Inherits bayrağını ayarlayarak bağımlılık özelliğiniz için özellik devralmayı etkinleştirebilirsiniz. Özellik devralma, ebeveyn ve çocuk öğelerin ortak bir özelliğe sahip olduğu senaryolar için kullanışlıdır ve çocuk öğenin bu ortak özellik için ebeveyn değerini devralmasının mantıklı olduğu durumlar için idealdir. Devralınabilir bir özellik örneği, DataContext kullanan bağlama işlemlerini destekleyen özelliğidir.

  • Bağımlılık özelliğinizin algılanması veya gezinti günlüğü hizmetleri tarafından kullanılması gerektiğini belirtmek için Journal bayrağını ayarlayın. Örneğin, SelectedIndex özelliği uygulamaların seçili öğelerin günlük geçmişini tutmasını önermek için Journal bayrağını ayarlar.

Salt okunur bağımlılık özellikleri

Salt okunur bir bağımlılık özelliği tanımlayabilirsiniz. Tipik bir senaryo, iç durumu depolayan bir bağımlılık özelliğidir. Örneğin, IsMouseOver salt okunurdur çünkü durumu yalnızca fare girişi tarafından belirlenebilir. Daha fazla bilgi için bkz: Salt okunur bağımlılık özellikleri.

Koleksiyon türü bağımlılık özellikleri

Koleksiyon türü bağımlılık özelliklerinin, başvuru türleri için varsayılan bir değer ayarlama ve koleksiyon öğeleri için veri bağlama desteği gibi dikkate alınması gereken ek uygulama sorunları vardır. Daha fazla bilgi için bkz.Koleksiyon türü bağımlılık özelliklerini .

Bağımlılık özelliğinin güvenliği

Genellikle bağımlılık özelliklerini genel özellikler ve DependencyProperty tanımlayıcı alanlarını public static readonly alanları olarak ilan edeceksiniz. protectedgibi daha kısıtlayıcı bir erişim düzeyi belirtirseniz, bağımlılık özelliğine yine de tanımlayıcısı aracılığıyla özellik sistemi API'leri ile birlikte erişilebilir. Korumalı bir tanımlayıcı alanına bile WPF meta veri raporlama veya LocalValueEnumeratorgibi değer belirleme API'leri aracılığıyla erişilebilir. Daha fazla bilgi için bkz. Bağımlılık özelliği güvenliği.

Salt okunur olan bağımlılık özellikleri için, RegisterReadOnly döndürülen değer DependencyPropertyKeyolur ve genellikle DependencyPropertyKey sınıfınızın bir public üyesi yapmazsınız. WPF özellik sistemi DependencyPropertyKey kodunuzun dışına yaymadığından, salt okunur bağımlılık özelliği, okuma-yazma bağımlılık özelliğinden daha iyi set güvenliğe sahiptir.

Bağımlılık özellikleri ve sınıf oluşturucuları

Yönetilen kod programlamada genellikle kod çözümleme araçları tarafından zorlanan, sınıf oluşturucularının sanal yöntemleri çağırmaması gereken genel bir ilke vardır. Bunun nedeni, temel oluşturucuların türetilmiş bir sınıf oluşturucusu başlatılırken çağrılabilmesi ve temel oluşturucu tarafından çağrılan bir sanal yöntemin türetilmiş sınıfın tam olarak başlatılmasından önce çalıştırılabilmesidir. zaten DependencyObjecttüretilen bir sınıftan türetdiğinizde, özellik sistemi sanal yöntemleri dahili olarak çağırır ve kullanıma sunar. Bu sanal yöntemler WPF özellik sistemi hizmetlerinin bir parçasıdır. Yöntemleri geçersiz kılma, türetilmiş sınıfların değer belirlemeye katılmasını sağlar. Çalışma zamanı başlatmayla ilgili olası sorunları önlemek için, belirli bir oluşturucu desenini izlemediğiniz sürece sınıfların oluşturucuları içinde bağımlılık özelliği değerlerini ayarlamamalısınız. Daha fazla bilgi için bkz. DependencyObjects için güvenli oluşturucu desenleri.

Ayrıca bakınız