XAML kaynaklarına genel bakış (WPF .NET)

Kaynak, uygulamanızın farklı yerlerinde yeniden kullanılabilen bir nesnedir. Kaynaklara örnek olarak fırçalar ve stiller verilebilir. Bu genel bakış, Genişletilebilir Uygulama Biçimlendirme Dili'nde (XAML) kaynakların nasıl kullanılacağını açıklar. Ayrıca kod kullanarak kaynaklar oluşturabilir ve bunlara erişebilirsiniz.

Dekont

Bu makalede açıklanan XAML kaynakları genellikle bir uygulamaya eklenen içerik, veri veya ekli dosyalar gibi dosyalar olan uygulama kaynaklarından farklıdır.

Önemli

.NET 7 ve .NET 6 için Masaüstü Kılavuzu belgeleri yapım aşamasındadır.

XAML'de kaynakları kullanma

Aşağıdaki örnek, bir SolidColorBrush sayfanın kök öğesinde kaynak olarak tanımlar. Örnek daha sonra kaynağa başvurur ve bunu kullanarak , TextBlockButtonve Ellipsegibi birkaç alt öğeye ait özellikleri ayarlar.

<Window x:Class="resources.ResExample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ResExample" Height="400" Width="300">
    <Window.Resources>
        <SolidColorBrush x:Key="MyBrush" Color="#05E0E9"/>
        <Style TargetType="Border">
            <Setter Property="Background" Value="#4E1A3D" />
            <Setter Property="BorderThickness" Value="5" />
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <LinearGradientBrush>
                        <GradientStop Offset="0.0" Color="#4E1A3D"/>
                        <GradientStop Offset="1.0" Color="Salmon"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="TextBlock" x:Key="TitleText">
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="Foreground" Value="#4E87D4"/>
            <Setter Property="FontFamily" Value="Trebuchet MS"/>
            <Setter Property="Margin" Value="0,10,10,10"/>
        </Style>
        <Style TargetType="TextBlock" x:Key="Label">
            <Setter Property="HorizontalAlignment" Value="Right"/>
            <Setter Property="FontSize" Value="13"/>
            <Setter Property="Foreground" Value="{StaticResource MyBrush}"/>
            <Setter Property="FontFamily" Value="Arial"/>
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="Margin" Value="0,3,10,0"/>
        </Style>
    </Window.Resources>

    <Border>
        <StackPanel>
            <TextBlock Style="{StaticResource TitleText}">Title</TextBlock>
            <TextBlock Style="{StaticResource Label}">Label</TextBlock>
            <TextBlock HorizontalAlignment="Right" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />
            <Button HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>
            <Ellipse HorizontalAlignment="Center" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="10" />
        </StackPanel>
    </Border>

</Window>

Her çerçeve düzeyi öğesinin (FrameworkElement veya FrameworkContentElement) tanımlı kaynakları içeren bir tür olan bir ResourceDictionary özelliği vardırResources. Gibi herhangi bir Buttonöğede kaynak tanımlayabilirsiniz. Ancak, kaynaklar genellikle örnekteki Window kök öğesinde tanımlanır.

Kaynak sözlüğündeki her kaynağın benzersiz bir anahtarı olmalıdır. İşaretleme içinde kaynakları tanımladığınızda, benzersiz anahtarı x:Key Yönergesi aracılığıyla atarsınız. Genellikle anahtar bir dizedir; ancak, uygun işaretleme uzantılarını kullanarak bunu diğer nesne türlerine de ayarlayabilirsiniz. Kaynaklar için dize olmayan anahtarlar WPF'deki belirli özellik alanları tarafından kullanılır; özellikle stiller, bileşen kaynakları ve veri stili için kullanılır.

Kaynağın anahtar adını belirten kaynak işaretleme uzantısı söz dizimi ile tanımlı bir kaynak kullanabilirsiniz. Örneğin, kaynağı başka bir öğedeki bir özelliğin değeri olarak kullanın.

<Button Background="{StaticResource MyBrush}"/>
<Ellipse Fill="{StaticResource MyBrush}"/>

Yukarıdaki örnekte, XAML yükleyicisi üzerindeki Buttonözelliğin Background değerini {StaticResource MyBrush} işlediğinde, kaynak arama mantığı önce öğesi için Button kaynak sözlüğünü denetler. Kaynak anahtarının MyBrush tanımı yoksa Button (bu örnekte yoktur; kaynak koleksiyonu boştur), arama sonrasında öğesinin Buttonüst öğesini denetler. Kaynak üst öğede tanımlanmamışsa, bulunana kadar nesnenin mantıksal ağacını yukarı doğru denetlemeye devam eder.

Kök öğesinde kaynakları tanımlarsanız, mantıksal ağaçtaki veya Pagegibi Window tüm öğeler buna erişebilir. Ayrıca, kaynağın temsil ettiği aynı türü kabul eden herhangi bir özelliğin değerini ayarlamak için aynı kaynağı yeniden kullanabilirsiniz. Önceki örnekte, aynı MyBrush kaynak iki farklı özellik ayarlar: Button.Background ve Ellipse.Fill.

Statik ve dinamik kaynaklar

Kaynağa statik veya dinamik olarak başvurulabilir. Başvurular StaticResource İşaretlemeyi Uzantısı veya DynamicResource İşaretlemeyi Uzantısı kullanılarak oluşturulur. İşaretlemeyi genişletme, işaretleme uzantısının öznitelik dizesini işlemesini ve nesneyi bir XAML yükleyicisine döndürmesini sağlayarak bir nesne başvurusu belirtmenize olanak tanıyan bir XAML özelliğidir. İşaretlemeyi genişletme davranışı hakkında daha fazla bilgi için bkz . İşaretlemeyi Genişletmeler ve WPF XAML.

Bir işaretleme uzantısı kullandığınızda, genellikle belirli bir işaretleme uzantısı tarafından işlenen dize biçiminde bir veya daha fazla parametre sağlarsınız. StaticResource İşaretlemeyi Uzantısı, kullanılabilir tüm kaynak sözlüklerinde bu anahtarın değerini arayarak bir anahtarı işler. İşleme, yükleme işleminin özellik değerini ataması gereken yük sırasında gerçekleşir. DynamicResource İşaretleme Uzantısı bunun yerine bir ifade oluşturarak bir anahtarı işler ve uygulama çalıştırılana kadar bu ifade değerlendirilmez ve bu sırada ifade bir değer sağlamak üzere değerlendirilir.

Bir kaynağa başvururken, statik kaynak başvurusu mu yoksa dinamik kaynak başvurusu mu kullandığınızı aşağıdaki noktalar etkileyebilir:

  • Uygulamanız için kaynakları nasıl oluşturduğunuza ilişkin genel tasarımı belirlerken (sayfa başına, uygulamada, gevşek XAML'de veya yalnızca kaynak derlemesinde), aşağıdakileri göz önünde bulundurun:

  • Uygulamanın işlevselliği. Kaynakları gerçek zamanlı olarak güncelleştirmek, uygulama gereksinimlerinizin bir parçası mı?

  • Bu kaynak başvuru türünün ilgili arama davranışı.

  • Belirli özellik veya kaynak türü ve bu türlerin yerel davranışı.

Statik kaynaklar

Statik kaynak başvuruları aşağıdaki durumlarda en iyi sonucu sağlar:

  • Uygulama tasarımınız kaynaklarının çoğunu sayfa veya uygulama düzeyindeki kaynak sözlüklerine yoğunlaştırıyor.

    Statik kaynak başvuruları, sayfayı yeniden yükleme gibi çalışma zamanı davranışlarına göre yeniden değerlendirilmez. Bu nedenle, kaynağınıza ve uygulama tasarımınıza bağlı olarak gerekli olmadığında çok fazla sayıda dinamik kaynak başvurusundan kaçınmanın bazı performans yararları olabilir.

  • veya Freezableüzerinde DependencyObject olmayan bir özelliğin değerini ayarlıyorsunuz.

  • Uygulamalar arasında paylaşılan bir DLL'de derlenmiş bir kaynak sözlüğü oluşturuyorsunuz.

  • Özel denetim için tema oluşturuyorsunuz ve temalar içinde kullanılan kaynakları tanımlıyorsunuz.

    Bu durumda, genellikle dinamik kaynak başvurusu arama davranışını istemezsiniz. Bunun yerine, aramanın tahmin edilebilir olması ve temada kendi kendine bulunması için statik kaynak başvuru davranışını kullanın. Dinamik kaynak başvurusuyla, temadaki bir başvuru bile çalışma zamanına kadar değerlendirilmeden bırakılır. Ayrıca, tema uygulandığında, bazı yerel öğelerin temanızın başvurmaya çalıştığı bir anahtarı yeniden tanımlama olasılığı vardır ve yerel öğe aramada temanın kendisinden önce gelir. Böyle bir durumda temanız beklendiği gibi davranmaz.

  • Çok sayıda bağımlılık özelliği ayarlamak için kaynakları kullanıyorsunuz. Bağımlılık özellikleri, özellik sistemi tarafından etkinleştirildiği gibi etkin değer önbelleğe alma özelliğine sahiptir, bu nedenle bir bağımlılık özelliği için yük zamanında değerlendirilebilecek bir değer sağlarsanız, bağımlılık özelliğinin yeniden değerlendirilen bir ifadeyi denetlemesi gerekmez ve son etkin değeri döndürebilir. Bu teknik bir performans avantajı olabilir.

  • Tüm tüketiciler için temel alınan kaynağı değiştirmek veya x:Shared Özniteliğini kullanarak her tüketici için ayrı yazılabilir örnekler tutmak istiyorsunuz.

Statik kaynak arama davranışı

Aşağıda, statik kaynağa bir özellik veya öğe tarafından başvurulduğunda otomatik olarak gerçekleşen arama işlemi açıklanmaktadır:

  1. Arama işlemi, özelliği ayarlayan öğesi tarafından tanımlanan kaynak sözlüğünde istenen anahtarı denetler.

  2. Arama işlemi daha sonra mantıksal ağacı yukarı doğru üst öğeye ve kaynak sözlüğüne doğru kaydırır. Kök öğeye ulaşılana kadar bu işlem devam eder.

  3. Uygulama kaynakları denetlendi. Uygulama kaynakları, WPF uygulamanızın nesnesi tarafından tanımlanan kaynak sözlüğündeki Application kaynaklardır.

Kaynak sözlüğü içindeki statik kaynak başvuruları, kaynak başvurusundan önce sözcük temelli olarak tanımlanmış bir kaynağa başvurmalıdır. İletme başvuruları statik kaynak başvurusuyla çözümlenemez. Bu nedenle kaynak sözlüğü yapınızı, kaynakların ilgili kaynak sözlüğünde veya başında tanımlandığı şekilde tasarlayın.

Statik kaynak araması temalara veya sistem kaynaklarına genişletilebilir, ancak bu arama yalnızca XAML yükleyicisi isteği karşıladığı için desteklenir. Erteleme, sayfa yüklendiğinde çalışma zamanı temasının uygulamaya düzgün şekilde uygulanabilmesi için gereklidir. Ancak, tema kullanıcı tarafından gerçek zamanlı olarak değiştirildiğinde bu tür başvurular yeniden değerlendirilmediğinden, yalnızca temalarda veya sistem kaynakları olarak var olduğu bilinen anahtarlara statik kaynak başvuruları önerilmez. Tema veya sistem kaynakları istediğinizde dinamik kaynak başvurusu daha güvenilirdir. Bunun istisnası, tema öğesinin kendisinin başka bir kaynak istemesidir. Bu başvurular, daha önce bahsedilen nedenlerle statik kaynak başvuruları olmalıdır.

Statik kaynak başvurusu bulunamazsa özel durum davranışı değişir. Kaynak ertelendiyse, özel durum çalışma zamanında gerçekleşir. Kaynak ertelenmezse, özel durum yükleme zamanında oluşur.

Dinamik kaynaklar

Dinamik kaynaklar şu durumlarda en iyi şekilde çalışır:

  • Sistem kaynakları veya kullanıcı tarafından ayarlanabilen kaynaklar da dahil olmak üzere kaynağın değeri, çalışma zamanına kadar bilinmeyen koşullara bağlıdır. Örneğin, , veya SystemParameterstarafından SystemColorsSystemFontskullanıma sunulan sistem özelliklerine başvuran ayarlayıcı değerleri oluşturabilirsiniz. Bu değerler gerçekten dinamiktir çünkü sonuçta kullanıcı ve işletim sisteminin çalışma zamanı ortamından gelirler. Sayfa düzeyinde kaynak erişiminin de değişikliği yakalaması gereken, değişebilen uygulama düzeyinde temalarınız da olabilir.

  • Özel denetim için tema stilleri oluşturuyor veya tema stillerine başvuruda bulunuyorsunuz.

  • Bir uygulama ömrü boyunca içeriğini ResourceDictionary ayarlamayı planlıyorsunuz.

  • İleriye doğru başvuru gerekebilecek bağımlılıklara sahip karmaşık bir kaynak yapısına sahipsiniz. Statik kaynak başvuruları iletme başvurularını desteklemez, ancak dinamik kaynak başvuruları bunları destekler çünkü kaynağın çalışma zamanına kadar değerlendirilmesi gerekmez ve bu nedenle ileriye doğru başvurular ilgili bir kavram değildir.

  • Derleme veya çalışma kümesi açısından büyük bir kaynağa başvuruda çalışıyorsunuz ve sayfa yüklendiğinde kaynak hemen kullanılamayabilir. Sayfa yüklendiğinde statik kaynak başvuruları her zaman XAML'den yüklenir. Ancak, dinamik kaynak başvurusu kullanılana kadar yüklenmez.

  • Ayarlayıcı değerlerinin temalardan veya diğer kullanıcı ayarlarından etkilenen diğer değerlerden gelebileceği bir stil oluşturuyorsunuz.

  • Uygulama ömrü boyunca mantıksal ağaçta yeniden ayrıştırılmış olabilecek öğelere kaynak uyguluyorsunuz. Üst öğeyi değiştirmek, kaynak arama kapsamını da değiştirebilir, bu nedenle yeni kapsam temelinde yeniden değerlendirilen bir öğe için kaynağın yeniden değerlendirilmesini istiyorsanız, her zaman dinamik bir kaynak başvurusu kullanın.

Dinamik kaynak arama davranışı

Dinamik kaynak başvurusu için kaynak arama davranışı, veya SetResourceReferenceçağrısı FindResource yaparsanız kodunuzdaki arama davranışına paralel olur:

  1. Arama, özelliği ayarlayan öğesi tarafından tanımlanan kaynak sözlüğünde istenen anahtarı denetler:

  2. Arama, mantıksal ağacı yukarı doğru üst öğeye ve kaynak sözlüğüne doğru kaydırır. Kök öğeye ulaşılana kadar bu işlem devam eder.

  3. Uygulama kaynakları denetlendi. Uygulama kaynakları, WPF uygulamanızın nesnesi tarafından tanımlanan kaynak sözlüğündeki Application kaynaklardır.

  4. Tema kaynak sözlüğü şu anda etkin olan tema için denetlendi. Tema çalışma zamanında değişirse, değer yeniden değerlendirilir.

  5. Sistem kaynakları denetlendi.

Özel durum davranışı (varsa) değişir:

  • Bir çağrı tarafından FindResource bir kaynak istendiyse ve bulunamazsa, bir özel durum oluşturulur.

  • Bir çağrı tarafından TryFindResource bir kaynak istendiyse ve bulunamazsa, hiçbir özel durum oluşturulur ve döndürülen değer olur null. Ayarlanan özellik kabul nulletmiyorsa, ayarlanan özelliğe bağlı olarak daha derin bir özel durum oluşturulabilir.

  • XAML'de dinamik bir kaynak başvurusu tarafından bir kaynak istendiyse ve bulunamazsa, davranış genel özellik sistemine bağlıdır. Genel davranış, kaynağın bulunduğu düzeyde hiçbir özellik ayarı işlemi gerçekleşmedi gibi olur. Örneğin, değerlendirilemeyen bir kaynağı kullanarak tek bir düğme öğesinde arka planı ayarlamaya çalışırsanız, değer kümesi sonucu yoktur, ancak geçerli değer yine de özellik sistemindeki diğer katılımcılardan ve değer önceliğinden gelebilir. Örneğin, arka plan değeri hala yerel olarak tanımlanmış bir düğme stilinden veya tema stilinden gelebilir. Tema stilleri tarafından tanımlanmayan özellikler için, başarısız bir kaynak değerlendirmesinden sonra geçerli değer özellik meta verilerindeki varsayılan değerden gelebilir.

Kısıtlamalar

Dinamik kaynak başvurularının bazı önemli kısıtlamaları vardır. Aşağıdaki koşullardan en az biri doğru olmalıdır:

Ayarlanan özelliğin bir DependencyProperty veya Freezable özelliği olması gerektiğinden, özellik değişikliği (değiştirilen dinamik kaynak değeri) özellik sistemi tarafından kabul edildiğinden özellik değişikliklerinin çoğu kullanıcı arabirimine yayılabilir. Denetimlerin çoğu, bir değişiklik ve bu özelliğin düzeni etkileyebileceği bir denetimin başka bir DependencyProperty düzenini zorlayan mantık içerir. Ancak, dynamicresource biçimlendirme uzantısına sahip olan tüm özelliklerin kullanıcı arabiriminde gerçek zamanlı güncelleştirmeler sağlaması garanti edilmez. Bu işlev yine de özelliğe bağlı olarak ve özelliğin sahibi olan türe veya uygulamanızın mantıksal yapısına bağlı olarak değişebilir.

Stiller, DataTemplates ve örtük anahtarlar

içindeki ResourceDictionary tüm öğelerin bir anahtarı olmalıdır ancak bu, tüm kaynakların açık x:Keybir öğesi olması gerektiği anlamına gelmez. Çeşitli nesne türleri, anahtar değerinin başka bir özelliğin değerine bağlı olduğu bir kaynak olarak tanımlandığında örtük anahtarı destekler. Bu anahtar türü örtük anahtar olarak bilinir ve x:Key öznitelik açık bir anahtardır. Açık bir anahtar belirterek herhangi bir örtük anahtarın üzerine yazabilirsiniz.

Kaynaklar için önemli senaryolardan biri, bir Styletanımladığınız senaryodur. Aslında, stiller doğal olarak yeniden kullanım için tasarlandığından, Style neredeyse her zaman bir kaynak sözlüğünde giriş olarak tanımlanır. Stiller hakkında daha fazla bilgi için bkz . Stiller ve şablonlar (WPF .NET).

Denetim stilleri hem ile oluşturulabilir hem de örtük bir anahtarla başvurulabilir. Denetimin varsayılan görünümünü tanımlayan tema stilleri bu örtük anahtarı kullanır. bunu isteme açısından, örtük anahtar denetimin kendisidir Type . Kaynakları tanımlama açısından, örtük anahtar stilin anahtarıdır TargetType . Bu nedenle, özel denetimler için temalar oluşturuyorsanız veya mevcut tema stilleriyle etkileşim kuran stiller oluşturuyorsanız, bunun Styleiçin bir x:Key Yönergesi belirtmeniz gerekmez. Temalı stilleri kullanmak istiyorsanız, herhangi bir stil belirtmeniz gerekmez. Örneğin, kaynağın anahtarı yok gibi görünse Style de aşağıdaki stil tanımı çalışır:

<Style TargetType="Button">
    <Setter Property="Background" Value="#4E1A3D" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="BorderThickness" Value="5" />
    <Setter Property="BorderBrush">
        <Setter.Value>
            <LinearGradientBrush>
                <GradientStop Offset="0.0" Color="#4E1A3D"/>
                <GradientStop Offset="1.0" Color="Salmon"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
</Style>

Bu stilin gerçekten bir anahtarı vardır: örtük anahtar: System.Windows.Controls.Button türü. İşaretlemede, doğrudan tür adı olarak bir TargetType belirtebilirsiniz (veya isteğe bağlı olarak bir döndürmek Typeiçin {x:Type...} kullanabilirsiniz.

WPF tarafından kullanılan varsayılan tema stili mekanizmaları aracılığıyla, bu stil, özelliği veya stil için belirli bir kaynak başvurusu belirtmeye Style çalışmasa Button bile sayfadaki bir Button çalışma zamanı stili olarak uygulanır. Sayfada tanımlanan stiliniz, tema sözlüğü stiliyle aynı anahtar kullanılarak, arama dizisinde tema sözlüğü stilinden daha önce bulunur. Sayfanın herhangi bir yerinde belirtebilirsiniz <Button>Hello</Button> ve ile tanımladığınız TargetTypeButton stil bu düğmeye uygulanır. İsterseniz, işaretlemenizdeki netlik için stili yine de açıkça aynı tür değeriyle TargetType anahtarlayabilirsiniz, ancak bu isteğe bağlıdır.

Stiller için örtük tuşlar ise OverridesDefaultStyletruedenetime uygulanmaz. (Ayrıca, denetimin OverridesDefaultStyle bir örneğinde açıkça değil, denetim sınıfı için yerel davranışın bir parçası olarak ayarlanabileceğini unutmayın.) Ayrıca, türetilmiş sınıf senaryoları için örtük anahtarları desteklemek için denetimin geçersiz kılması DefaultStyleKey gerekir (WPF'nin parçası olarak sağlanan tüm mevcut denetimler bu geçersiz kılmayı içerir). Stiller, temalar ve denetim tasarımı hakkında daha fazla bilgi için bkz . Stylable Denetimleri Tasarlama Yönergeleri.

DataTemplate ayrıca örtük bir anahtara sahiptir. için DataTemplate örtük anahtar, özellik değeridir DataType . DataType, açıkça {x:Type...} kullanmak yerine türün adı olarak da belirtilebilir. Ayrıntılar için bkz . Veri Şablon oluşturmaya genel bakış.

Ayrıca bkz.