Bağımlılık Özelliği Değer Önceliği

Bu konu başlığı altında, Windows Presentation Foundation (WPF) özellik sisteminin çalışmalarının bağımlılık özelliğinin değerini nasıl etkileyebileceği açıklanır ve özellik sisteminin hangi yönlerinin bir özelliğin etkin değerine uygulanacağı önceliği açıklanmaktadır.

Ön koşullar

Bu konu başlığında, WPF sınıflarında var olan bağımlılık özelliklerinin tüketicisi açısından bağımlılık özelliklerini anladığınız ve Bağımlılık Özelliklerine Genel Bakış konusunu okuduğunuz varsayılır. Bu konudaki örnekleri takip etmek için XAML'yi de anlamanız ve WPF uygulamalarının nasıl yazılması gerektiğini bilmeniz gerekir.

WPF Özellik Sistemi

WPF özellik sistemi, bağımlılık özelliklerinin değerinin çeşitli faktörler tarafından belirlenmesi için güçlü bir yol sunar; gerçek zamanlı özellik doğrulama, geç bağlama gibi özellikleri etkinleştirir ve diğer özellikler için değerlerdeki değişikliklerin ilgili özelliklerini bilgilendirir. Bağımlılık özelliği değerlerini belirlemek için kullanılan tam sıra ve mantık makul düzeyde karmaşıktır. Bu sırayı bilmek gereksiz özellik ayarını önlemenize yardımcı olur ve bağımlılık özelliği değerini etkilemeye veya tahmin etmeye yönelik bir girişimin neden beklediğiniz değerle sonuçlanmadığı konusunda karışıklığı da ortadan kaldırabilir.

Bağımlılık Özellikleri Birden Çok Yerde "Ayarlanmış" Olabilir

Aşağıda, aynı özelliğin (Background) değeri etkileyebilecek üç farklı "set" işlemine sahip olduğu örnek XAML verilmiştir.

<StackPanel>
    <StackPanel.Resources>
        <ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}">
            <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" 
                    BorderBrush="{TemplateBinding BorderBrush}">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Border>
        </ControlTemplate>
    </StackPanel.Resources>

    <Button Template="{StaticResource ButtonTemplate}" Background="Red">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Background" Value="Blue"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Yellow" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
        Which color do you expect?
    </Button>
</StackPanel>

Burada hangi rengin uygulanacağını bekliyorsunuz: kırmızı, yeşil veya mavi?

Animasyonlu değerler ve zorlama dışında, yerel özellik kümeleri en yüksek önceliğe ayarlanır. Bir değeri yerel olarak ayarlarsanız, tüm stillerin veya denetim şablonlarının üzerinde bile değerin yerine getirilmesini bekleyebilirsiniz. Burada örnekte Yerel Background olarak Kırmızı olarak ayarlanmıştır. Bu nedenle, bu kapsamda tanımlanan stil, bu kapsamdaki bu türdeki tüm öğelere uygulanabilecek örtük bir stil olsa da, özelliğe değerini vermek Background için en yüksek öncelik değildir. Bu Düğme örneğinden Kırmızı'nın yerel değerini kaldırdıysanız, stil öncelikli olur ve düğme stilden Arka plan değerini alır. Stilin içinde tetikleyiciler önceliklidir, bu nedenle fare üzerindeyse düğme mavi, aksi takdirde yeşil olur.

Bağımlılık Özellik Ayarı Öncelik Listesi

Aşağıda, bağımlılık özelliklerinin çalışma zamanı değerlerini atarken özellik sisteminin kullandığı kesin sıra yer alır. En yüksek öncelik önce listelenir. Bu liste, Bağımlılık Özelliklerine Genel Bakış'ta yapılan bazı genelleştirmeleri genişletir.

  1. Özellik sistemi zorlaması. Zorlamayla ilgili ayrıntılar için bu konunun devamında yer alan Zorlama, Animasyon ve Temel Değer konularına bakın.

  2. Etkin animasyonlar veya Ayrı Tutma davranışına sahip animasyonlar. Herhangi bir pratik etkiye sahip olmak için, bir özelliğin animasyonunun, bu değer yerel olarak ayarlanmış olsa bile temel (animasyonsuz) değere göre önceliğe sahip olması gerekir. Ayrıntılar için bu konunun devamında yer alan Zorlama, Animasyon ve Temel Değer konularına bakın.

  3. Yerel değer. Yerel bir değer, XAML'de öznitelik veya özellik öğesi olarak veya belirli bir örneğin özelliğini kullanarak API'ye SetValue yapılan bir çağrıyla da eşitlenen "sarmalayıcı" özelliğinin kolaylığıyla ayarlanabilir. Bağlama veya kaynak kullanarak yerel bir değer ayarlarsanız, bunların her birinin öncelikleri doğrudan bir değer ayarlanmış gibi davranır.

  4. TemplatedParent şablon özellikleri. Bir öğenin bir TemplatedParent şablonun ( ControlTemplate veya DataTemplate) parçası olarak oluşturulmuş olup olmadığını içeren bir öğesi vardır. Bunun ne zaman geçerli olduğuyla ilgili ayrıntılar için bu konunun devamında templatedParent bölümüne bakın. Şablonda aşağıdaki öncelik geçerlidir:

    1. Şablondan TemplatedParent tetikleyiciler.

    2. Şablondaki TemplatedParent özellik kümeleri (genellikle XAML öznitelikleri aracılığıyla).

  5. Örtük stil. Yalnızca özelliği için Style geçerlidir. Style özelliği, herhangi bir stil kaynağı tarafından bu öğenin türüyle eşleşen bir anahtarla doldurulur. Bu stil kaynağının sayfada veya uygulamada mevcut olması gerekir; örtük stil kaynağı için arama, temalara geçmiyor.

  6. Stil tetikleyicileri. Sayfadaki veya uygulamadaki stiller içindeki tetikleyiciler (bu stiller açık veya örtük stiller olabilir, ancak daha düşük önceliğe sahip varsayılan stillerden değil).

  7. Şablon tetikleyicileri. Stil içindeki bir şablondan veya doğrudan uygulanan bir şablondan herhangi bir tetikleyici.

  8. Stil ayarlayıcıları. Sayfadaki veya uygulamadaki stiller içindeki değerler Setter .

  9. Varsayılan (tema) stili. Bunun ne zaman geçerli olduğu ve tema stillerinin tema stilleri içindeki şablonlarla ilişkisi hakkında ayrıntılı bilgi için bu konunun devamında yer alan Varsayılan (Tema) Stilleri bölümüne bakın. Varsayılan stilde aşağıdaki öncelik sırası uygulanır:

    1. Tema stilinde etkin tetikleyiciler.

    2. Tema stilinde ayarlayıcılar.

  10. Devralma. Birkaç bağımlılık özelliği, değerlerini üst öğeden alt öğelere devralır, böylece bir uygulama genelinde her öğede özel olarak ayarlanması gerekmez. Ayrıntılar için bkz. Özellik Değeri Devralma.

  11. Bağımlılık özelliği meta verilerinden varsayılan değer. Belirli bir bağımlılık özelliği, söz konusu özelliğin özellik sistemi kaydı tarafından belirlenen varsayılan bir değere sahip olabilir. Ayrıca, bir bağımlılık özelliğini devralan türetilmiş sınıflar, söz konusu meta verileri (varsayılan değer dahil) tür bazında geçersiz kılma seçeneğine sahiptir. Daha fazla bilgi için bkz . Bağımlılık Özelliği Meta Verileri . Devralma varsayılan değerden önce denetlendiğinden, devralınan bir özellik için üst öğe varsayılan değeri bir alt öğeden önceliklidir. Sonuç olarak, devralınabilir bir özellik herhangi bir yerde ayarlanmazsa, alt öğe varsayılan değeri yerine kökte veya üst öğede belirtilen varsayılan değer kullanılır.

Templatedparent

Öncelik öğesi olarak TemplatedParent, doğrudan standart uygulama işaretlemesinde bildirdiğiniz bir öğenin hiçbir özelliği için geçerli değildir. TemplatedParent kavramı yalnızca şablonun uygulaması aracılığıyla ortaya çıkan bir görsel ağaç içindeki alt öğeler için mevcuttur. Özellik sistemi şablonda TemplatedParent bir değer ararken, bu öğeyi oluşturan şablonu arar. Şablondaki TemplatedParent özellik değerleri genellikle alt öğede yerel bir değer olarak ayarlanmış gibi davranır, ancak şablonlar paylaşılma olasılığı olduğundan yerel değere kıyasla bu daha az öncelik vardır. Ayrıntılar için bkz. TemplatedParent.

Stil Özelliği

Daha önce açıklanan arama sırası, biri hariç tüm olası bağımlılık özellikleri için geçerlidir: Style özelliği. Style özelliği, kendi stili oluşturulamadığı için benzersizdir, bu nedenle 5 ile 8 arasındaki öncelik öğeleri uygulanmaz. Ayrıca, animasyon veya zorlama Style önerilmez (ve animasyon oluşturmak Style için özel bir animasyon sınıfı gerekir). Bu, özelliğin Style ayarlanacağı üç yolu bırakır:

  • Açık stil. Style özelliği doğrudan ayarlanır. Çoğu senaryoda stil satır içinde tanımlanmaz, bunun yerine açık anahtarla kaynak olarak başvurulur. Bu durumda Style özelliği, yerel bir değer, öncelik öğesi 3 gibi davranır.

  • Örtük stil. Style özelliği doğrudan ayarlanmadı. Ancak , Style kaynak arama dizisinde (sayfa, uygulama) bir düzeyde bulunur ve stilin uygulanacağı türle eşleşen bir kaynak anahtarı kullanılarak anahtarlanır. Bu durumda özelliğin Style kendisi, dizide 5. öğe olarak tanımlanan bir önceliğe göre hareket eder. Bu koşul özelliğine Style karşı kullanılarak DependencyPropertyHelper ve sonuçlarda aranarak ImplicitStyleReference algılanabilir.

  • Tema stili olarak da bilinen varsayılan stil.Style özelliği doğrudan ayarlanmaz ve aslında çalışma zamanına kadar kadar okur null . Bu durumda, stil WPF sunu altyapısının bir parçası olan çalışma zamanı tema değerlendirmesinden gelir.

Temalarda bulunmayan örtük stiller için türün tam olarak eşleşmesi gerekir. Türetilmiş bir MyButtonButtonsınıf için Buttonörtük olarak bir stil kullanmaz.

Varsayılan (Tema) Stilleri

WPF ile birlikte gelen her denetimin varsayılan stili vardır. Bu varsayılan stil büyük olasılıkla temaya göre farklılık gösterir. Bu nedenle bu varsayılan stil bazen tema stili olarak adlandırılır.

Bir denetimin varsayılan stilinde bulunan en önemli bilgiler, tema stilinde özelliği için ayarlayıcı olarak bulunan denetim şablonudur Template . Varsayılan stillerden hiçbir şablon olmasaydı, özel bir stilin parçası olarak özel şablonu olmayan bir denetim hiç görsel görünüme sahip olmazdı. Varsayılan stildeki şablon, her denetimin görsel görünümünü temel bir yapıya verir ve ayrıca şablonun görsel ağacında tanımlanan özelliklerle ilgili denetim sınıfı arasındaki bağlantıları tanımlar. Her denetim, şablonu tamamen değiştirmeden denetimin görsel görünümünü etkileyebilecek bir özellik kümesi sunar. Örneğin, bir Thumb denetimin bileşeni ScrollBarolan varsayılan görsel görünümünü göz önünde bulundurun.

belirli Thumb özelleştirilebilir özelliklere sahiptir. varsayılan şablonu Thumb , eğim görünümü oluşturmak için birkaç iç içe Border bileşen içeren temel bir yapı / görsel ağaç oluşturur. Şablonun parçası olan bir özelliğin sınıf tarafından Thumb özelleştirme için kullanıma sunması amaçlanıyorsa, bu özelliğin şablon içinde bir TemplateBinding tarafından kullanıma sunması gerekir. durumundaThumb, bu kenarlıkların çeşitli özellikleri veya BorderThicknessgibi Background özelliklere bir şablon bağlaması paylaşır. Ancak diğer bazı özellikler veya görsel düzenlemeler denetim şablonuna sabit olarak kodlanmıştır veya doğrudan temadan gelen değerlere bağlıdır ve şablonun tamamını değiştirmeden değiştirilemez. Genellikle, bir özellik şablonlu bir üst öğeden geliyorsa ve şablon bağlaması tarafından kullanıma sunulmadıysa, bunu hedeflemenin kolay bir yolu olmadığından stiller tarafından ayarlanamaz. Ancak bu özellik, uygulanan şablondaki özellik değeri devralma özelliğinden veya varsayılan değerden etkilenebilir.

Tema stilleri, tanımlarında anahtar olarak bir tür kullanır. Ancak, temalar belirli bir öğe örneğine uygulandığında, bu tür için tema araması, bir denetimde DefaultStyleKey özelliği denetlenerek gerçekleştirilir. Bu, örtük stillerin olduğu gibi değişmez Değer Türü'nü kullanmanın aksinedir. değeri DefaultStyleKey , uygulayıcı değiştirmese bile türetilmiş sınıflara devralır (özelliği değiştirmenin amaçlanan yolu, özelliği özellik düzeyinde geçersiz kılmak değil, bunun yerine özellik meta verilerindeki varsayılan değerini değiştirmektir). Bu dolaylılık, temel sınıfların başka bir stile sahip olmayan türetilmiş öğeler için tema stillerini tanımlamasını sağlar (veya daha da önemlisi, bu stil içinde bir şablonu yoktur ve bu nedenle varsayılan bir görsel görünümü yoktur). Bu nedenle, 'den türetebilirsiniz MyButton ve yine de varsayılan şablonu alırsınızButton.Button Denetim yazarıysanız MyButton ve farklı bir davranış istiyorsanız, farklı bir anahtar döndürmek için DefaultStyleKey üzerinde MyButton bağımlılık özelliği meta verilerini geçersiz kılabilir ve ardından denetiminizle MyButton birlikte paketlemeniz gereken şablon MyButton da dahil olmak üzere ilgili tema stillerini tanımlayabilirsiniz. Temalar, stiller ve denetim yazma hakkında daha fazla ayrıntı için bkz . Denetim Yazmaya Genel Bakış.

Dinamik Kaynak Başvuruları ve Bağlama

Dinamik kaynak başvuruları ve bağlama işlemleri, ayarlandıkları konumun önceliğine dikkat eder. Örneğin, yerel bir değere uygulanan dinamik kaynak öncelik öğesi 3'e göre hareket eder; tema stilindeki bir özellik ayarlayıcısı için bağlama, öncelik öğesi 9'da uygulanır ve bu şekilde devam eder. Dinamik kaynak başvurularının ve bağlamanın her ikisinin de uygulamanın çalışma zamanı durumundan değerleri alabilmesi gerektiğinden, bu, belirli bir özellik için özellik değeri önceliğini belirleme işleminin de çalışma süresine genişletilmesine neden olur.

Dinamik kaynak başvuruları kesinlikle özellik sisteminin bir parçası değildir, ancak yukarıda listelenen diziyle etkileşim kuran kendi arama sıralarına sahiptir. Bu öncelik, XAML Kaynakları'nda daha ayrıntılı bir şekilde belgelenmiştir. Bu önceliğin temel toplamı: öğeden sayfaya köke, uygulama, tema, sistemdir.

Dinamik kaynaklar ve bağlamalar, ayarlandıkları konumdan önceliğe sahiptir, ancak değer ertelenmiş olur. Bunun bir sonucu, bir dinamik kaynak veya bağlamayı yerel bir değere ayarlarsanız, yerel değerde yapılan herhangi bir değişikliğin dinamik kaynağın veya bağlamanın tamamen değiştirilmesidir. Yerel olarak ayarlanan değeri temizlemek için yöntemini çağırsanız ClearValue bile, dinamik kaynak veya bağlama geri yüklenmez. Aslında, dinamik kaynağı veya bağlaması olan bir özelliği çağırırsanız ClearValue (sabit yerel değer olmadan), bunlar da çağrı tarafından ClearValue temizlenir.

SetCurrentValue

SetCurrentValue yöntemi bir özelliği ayarlamanın başka bir yoludur, ancak öncelik sırasına göre değildir. Bunun yerine, SetCurrentValue önceki bir değerin kaynağının üzerine yazmadan bir özelliğin değerini değiştirmenize olanak tanır. Bu değere yerel bir değerin önceliğini vermeden, değer ayarlamak istediğiniz herhangi bir zamanı kullanabilirsiniz SetCurrentValue . Örneğin, bir özellik bir tetikleyici tarafından ayarlanırsa ve ardından aracılığıyla SetCurrentValuebaşka bir değer atanırsa, özellik sistemi tetikleyiciye saygı gösterir ve tetikleyicinin eylemi gerçekleşirse özellik değişir. SetCurrentValue , özelliğin değerini daha yüksek önceliğe sahip bir kaynak vermeden değiştirmenize olanak tanır. Benzer şekilde, bir bağlamanın üzerine yazmadan bir özelliğin değerini değiştirmek için de kullanabilirsiniz SetCurrentValue .

Zorlama, Animasyonlar ve Temel Değer

Hem zorlama hem de animasyon, bu SDK genelinde "temel değer" olarak ifade edilen bir değer üzerinde hareket eder. Bu nedenle temel değer, öğe 2'ye ulaşılana kadar öğelerde yukarı doğru değerlendirilerek belirlenen değerdir.

Bir animasyon için, bu animasyon belirli davranışlar için hem "Kimden" hem de "Kime" belirtmiyorsa veya animasyon tamamlandığında kasıtlı olarak temel değere geri dönüyorsa, temel değerin animasyonlu değer üzerinde bir etkisi olabilir. Bunu uygulamada görmek için Kimden, Hedef ve Animasyona Göre Hedef Değerleri Örneğini çalıştırın. Örnekte dikdörtgen yüksekliğinin yerel değerlerini, ilk yerel değerin animasyondaki herhangi bir "Kimden" değerinden farklı olacak şekilde ayarlamayı deneyin. Animasyonların "Kimden" değerlerini kullanarak hemen başladığını ve başlatıldıktan sonra temel değeri değiştirdiğini göreceksiniz. Animasyon, durdurularak FillBehaviortamamlandıktan sonra animasyondan önce bulunan değere döndürüleceğini belirtebilir. Daha sonra, temel değer belirleme için normal öncelik kullanılır.

Tek bir özelliğe birden çok animasyon uygulanabilir ve bu animasyonların her biri büyük olasılıkla değer öncesindeki farklı noktalardan tanımlanmış olabilir. Ancak, bu animasyonlar yalnızca daha yüksek önceliğe sahip animasyonu uygulamak yerine, potansiyel olarak değerlerini birleştirecektir. Bu, animasyonların tam olarak nasıl tanımlandığına ve animasyonlu olan değerin türüne bağlıdır. Özellikleri animasyonlandırma hakkında daha fazla bilgi için bkz . Animasyona Genel Bakış.

Zorlama, en yüksek düzeyde uygulanır. Zaten çalışan bir animasyon bile değer zorlamasına tabidir. WPF'deki bazı mevcut bağımlılık özellikleri yerleşik zorlamaya sahiptir. Özel bağımlılık özelliği için, özel bağımlılık özelliğini oluştururken meta verilerin bir parçası olarak bir CoerceValueCallback yazıp geri çağırma geçirerek zorlama davranışını tanımlarsınız. Ayrıca, türetilmiş bir sınıftaki bu özellik üzerindeki meta verileri geçersiz kılarak mevcut özelliklerin zorlama davranışını geçersiz kılabilirsiniz. Zorlama, temel değerle, o sırada bu kısıtlamalar mevcut olduğundan zorlama üzerindeki kısıtlamaların uygulanacağı şekilde etkileşim kurar, ancak temel değer hala korunur. Bu nedenle, zorlamadaki kısıtlamalar daha sonra kaldırılırsa, zorlama bu temel değere mümkün olan en yakın değeri döndürür ve potansiyel olarak tüm kısıtlamalar kaldırıldığında bir özellik üzerindeki zorlama etkisi sona erer. Zorlama davranışı hakkında daha fazla bilgi için bkz . Bağımlılık Özelliği Geri Çağırmaları ve Doğrulama.

Tetikleyici Davranışları

Denetimler genellikle tetikleyici davranışlarını temalarda varsayılan stillerinin bir parçası olarak tanımlar. Denetimlerde yerel özelliklerin ayarlanması, tetikleyicilerin kullanıcı odaklı olaylara görsel veya davranışsal olarak yanıt vermesini engelleyebilir. Özellik tetikleyicisinin en yaygın kullanımı, gibi IsSelecteddenetim veya durum özellikleri içindir. Örneğin, varsayılan olarak bir Button devre dışı bırakıldığında (için tetikleyiciIsEnabled) falseForeground tema stilindeki değer denetimin "gri" görünmesine neden olur. Ancak yerel Foreground bir değer ayarladıysanız, bu özellik tarafından tetiklenen senaryoda bile bu normal gri renk yerel özellik kümeniz tarafından öncelikli olarak geçersiz hale gelir. Tema düzeyinde tetikleyici davranışları olan özellikler için değerleri ayarlama konusunda dikkatli olun ve söz konusu denetim için hedeflenen kullanıcı deneyimine gereksiz şekilde müdahale etmediğinizden emin olun.

ClearValue ve Değer Önceliği

yöntemi, ClearValue bir öğede ayarlanan bir bağımlılık özelliğinden yerel olarak uygulanan tüm değerleri temizlemek için uygun bir yöntem sağlar. Ancak çağırma ClearValue , özellik kaydı sırasında meta verilerde belirlenen varsayılan değerin yeni etkin değer olduğunu garanti etmemektedir. Değer önceliği olan diğer tüm katılımcılar hala etkindir. Öncelik dizisinden yalnızca yerel olarak ayarlanan değer kaldırıldı. Örneğin, bu özelliğin de tema stiline göre ayarlandığı bir özelliği çağırırsanız ClearValue , tema değeri meta veri tabanlı varsayılan değer yerine yeni değer olarak uygulanır. Tüm özellik değeri katılımcılarını işlemden çıkarmak ve değeri kayıtlı meta veri varsayılanı olarak ayarlamak istiyorsanız, bağımlılık özelliği meta verilerini sorgulayarak bu varsayılan değeri kesin olarak elde edebilir ve ardından varsayılan değeri kullanarak özelliğini çağrısıyla SetValueyerel olarak ayarlayabilirsiniz.

Ayrıca bkz.