Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Windows Presentation Foundation (WPF) stil oluşturma ve şablon oluşturma, geliştiricilerin ve tasarımcıların ürünleri için görsel olarak cazip efektler ve tutarlı bir görünüm oluşturmasına olanak sağlayan bir özellik paketine başvurur. Bir uygulamanın görünümünü özelleştirirken, uygulamalar içinde ve uygulamalar arasında görünümün bakımını ve paylaşımını sağlayan güçlü bir stil ve şablon oluşturma modeli istiyorsunuz. WPF bu modeli sağlar.
WPF stil modelinin bir diğer özelliği de sunu ve mantığın ayrılmasıdır. Tasarımcılar, geliştiricilerin C# veya Visual Basic kullanarak programlama mantığı üzerinde çalıştığı aynı anda yalnızca XAML kullanarak bir uygulamanın görünümü üzerinde çalışabilir.
Bu genel bakış, uygulamanın stil ve şablon oluşturma yönlerine odaklanır ve veri bağlama kavramlarını tartışmaz. Veri bağlama hakkında bilgi için bkz. Veri Bağlamaya Genel Bakış.
Stillerin ve şablonların yeniden kullanılmasını sağlayan kaynakları anlamak önemlidir. Kaynaklar hakkında daha fazla bilgi için bkz . XAML kaynaklarına genel bakış.
Örnek
Bu genel bakışta sağlanan örnek kod, aşağıdaki çizimde gösterilen basit bir fotoğraf tarama uygulaması temel alır.
Bu basit fotoğraf örneği, görsel olarak ilgi çekici bir kullanıcı deneyimi oluşturmak için stil ve şablon oluşturmayı kullanır. Örnekte iki TextBlock öğesi ve görüntü listesine bağlı bir ListBox denetimi vardır.
Örneğin tamamı için bkz. Stil Oluşturma ve Şablon Oluşturma Örneğine Giriş.
Stil
Bir Style, birden çok öğeye özellik değerleri kümesi uygulamak için kullanışlı bir yol olarak düşünebilirsiniz. FrameworkElement veya FrameworkContentElement'den türetilen ve Window veya Buttongibi olan herhangi bir öğede stil kullanabilirsiniz.
Stil bildirmenin en yaygın yolu, XAML dosyasının Resources
bölümünde yer alan bir kaynaktır. Stiller kaynaklar olduğundan, tüm kaynaklar için geçerli olan aynı kapsama kurallarına uyarlar. Basitçe ifade edin, bir stili bildirdiğiniz yer, stilin uygulanabileceği yeri etkiler. Örneğin, stili uygulama tanımı XAML dosyanızın kök öğesinde bildirirseniz, stil uygulamanızın herhangi bir yerinde kullanılabilir.
Örneğin, aşağıdaki XAML kodu, bir TextBlock
için iki stil bildirir: biri otomatik olarak tüm TextBlock
öğelerine uygulanır, diğeri ise açıkça belirtilmesi gereken bir stildir.
<Window.Resources>
<!-- .... other resources .... -->
<!--A Style that affects all TextBlocks-->
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="14"/>
</Style>
<!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
<Style BasedOn="{StaticResource {x:Type TextBlock}}"
TargetType="TextBlock"
x:Key="TitleText">
<Setter Property="FontSize" Value="26"/>
<Setter Property="Foreground">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="#90DDDD" />
<GradientStop Offset="1.0" Color="#5BFFFF" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Yukarıda kullanılmakta olduğu bildirilen stillerin bir örneği aşağıda verilmiştir.
<StackPanel>
<TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>
Daha fazla bilgi için bkz . Denetim için stil oluşturma.
ControlTemplates
WPF'de, denetimin ControlTemplate denetimin görünümünü tanımlar. Yeni bir ControlTemplate tanımlayıp bir denetime atayarak denetimin yapısını ve görünümünü değiştirebilirsiniz. Çoğu durumda şablonlar, kendi özel denetimlerinizi yazmanız gerekmeyecek kadar esneklik sağlar.
Her denetimin Control.Template özelliğine atanmış varsayılan bir şablonu vardır. Şablon, denetimin görsel sunumunu denetimin özelliklerine bağlar. XAML'de şablon tanımladığınızdan, herhangi bir kod yazmadan denetimin görünümünü değiştirebilirsiniz. Her şablon, Buttongibi belirli bir denetim için tasarlanmıştır.
Genellikle XAML dosyasının Resources
bölümünde bir şablonu kaynak olarak bildirirsiniz. Tüm kaynaklarda olduğu gibi kapsam belirleme kuralları da geçerlidir.
Denetim şablonları bir stilden çok daha karmaşıktır. Bunun nedeni, denetim şablonunun denetimin tamamının görsel görünümünü yeniden yazması, stilin ise var olan denetime özellik değişikliklerini uygulamasıdır. Ancak, denetimin şablonu Control.Template
Tasarımcılar genellikle var olan bir şablonun kopyasını oluşturmanıza ve değiştirmenize olanak sağlar. Örneğin, Visual Studio WPF tasarımcısında bir CheckBox
denetimi seçin ve sağ tıklayıp şablonu düzenle >bir kopya oluştur'u seçin. Bu komut, stilinin birşablonu tanımlamasını sağlar.
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual1}"/>
<Setter Property="Background" Value="{StaticResource OptionMark.Static.Background1}"/>
<Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border1}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="checkBoxBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid x:Name="markGrid">
<Path x:Name="optionMark" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z " Fill="{StaticResource OptionMark.Static.Glyph1}" Margin="1" Opacity="0" Stretch="None"/>
<Rectangle x:Name="indeterminateMark" Fill="{StaticResource OptionMark.Static.Glyph1}" Margin="2" Opacity="0"/>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual1}"/>
<Setter Property="Padding" Value="4,-1,0,0"/>
... content removed to save space ...
Şablonun bir kopyasını düzenlemek, şablonların nasıl çalıştığını öğrenmenin harika bir yoludur. Yeni boş bir şablon oluşturmak yerine, bir kopyayı düzenlemek ve görsel sununun birkaç yönünü değiştirmek daha kolaydır.
Örnek için bkz. , denetimiçin bir şablon oluşturma.
ŞablonBağlama
Önceki bölümde tanımlanan şablon kaynağının TemplateBinding İşaretleme Uzantısıkullandığını fark etmiş olabilirsiniz.
TemplateBinding
, {Binding RelativeSource={RelativeSource TemplatedParent}}
ile yapılan bağlamaya benzer şekilde şablon senaryoları için iyileştirilmiş bir bağlama biçimidir.
TemplateBinding
, şablonun bölümlerini denetimin özelliklerine bağlamak için kullanışlıdır. Örneğin, her denetimin bir BorderThickness özelliği vardır. Şablondaki hangi öğenin bu denetim ayarından etkilendiğini yönetmek için bir TemplateBinding
kullanın.
ContentControl ve ItemsControl
ContentPresenter, ControlTemplate'nin ContentControl'inde bildirilirse, ContentPresenter, ContentTemplate ve Content özelliklerine otomatik olarak bağlanır. Benzer şekilde, bir ItemsPresenter, bir ControlTemplate'nin içindeki ItemsControl'de olan, otomatik olarak ItemTemplate ve Items özelliklerine bağlanır.
Veri Şablonları
Bu örnek uygulamada, fotoğraf listesine bağlı bir ListBox denetimi vardır.
<ListBox ItemsSource="{Binding Source={StaticResource MyPhotos}}"
Background="Silver" Width="600" Margin="10" SelectedIndex="0"/>
Bu ListBox şu anda aşağıdaki gibi görünür.
Denetimlerin çoğu bir tür içeriğe sahiptir ve bu içerik genellikle bağlandığınız verilerden gelir. Bu örnekte veriler fotoğrafların listesidir. WPF'de, verilerin görsel gösterimini tanımlamak için bir DataTemplate kullanırsınız. Temel olarak, bir DataTemplate içine koyduğunuz veriler, uygulamanın render edildiğinde nasıl görüneceğini belirler.
Örnek uygulamamızda her özel Photo
nesnesinin, görüntünün dosya yolunu belirten tür dizesinin Source
özelliği vardır. Şu anda fotoğraf nesneleri dosya yolları olarak görünür.
public class Photo
{
public Photo(string path)
{
Source = path;
}
public string Source { get; }
public override string ToString() => Source;
}
Public Class Photo
Sub New(ByVal path As String)
Source = path
End Sub
Public ReadOnly Property Source As String
Public Overrides Function ToString() As String
Return Source
End Function
End Class
Fotoğrafların görüntü olarak görünmesi için kaynak olarak bir DataTemplate oluşturursunuz.
<Window.Resources>
<!-- .... other resources .... -->
<!--DataTemplate to display Photos as images
instead of text strings of Paths-->
<DataTemplate DataType="{x:Type local:Photo}">
<Border Margin="3">
<Image Source="{Binding Source}"/>
</Border>
</DataTemplate>
</Window.Resources>
DataType özelliğinin TargetTypeStyle özelliğine benzer olduğuna dikkat edin.
DataTemplate kaynaklar bölümündeyse, bir türe DataType özelliğini belirttiğinizde ve bir x:Key
'yi atladığınızda, bu tür her görüldüğünde DataTemplate uygulanır. Her zaman DataTemplate'ı bir x:Key
olarak atayıp ve ardından StaticResource
olarak ayarlama seçeneğine sahipsiniz; bu, DataTemplate özelliği veya ItemTemplate özelliği gibi ContentTemplate türleri alan özellikler için geçerlidir.
Temel olarak, yukarıdaki örnekteki DataTemplate, bir Photo
nesnesi olduğunda, bir Imageiçinde Border olarak görünmesi gerektiğini tanımlar. Bu DataTemplateile uygulamamız artık şöyle görünür.
Veri şablon oluşturma modeli diğer özellikleri sağlar. Örneğin, HeaderedItemsControl veya Menugibi bir TreeView türü kullanarak diğer koleksiyonları içeren koleksiyon verilerini görüntülüyorsanız, bu durumda HierarchicalDataTemplatede mevcuttur. Başka bir veri şablon oluşturma özelliği, özel mantığa göre kullanılacak bir DataTemplateSelector seçmenize olanak tanıyan DataTemplateözelliğidir. Daha fazla bilgi için farklı veri şablon oluşturma özellikleri hakkında daha ayrıntılı bir tartışma sağlayan
Tetikleyiciler
Tetikleyici özellikleri ayarlar veya bir özellik değeri değiştiğinde veya bir olay tetiklendiğinde animasyon gibi eylemleri başlatır.
Style, ControlTemplateve DataTemplate'nin hepsinin tetikleyici kümesi içerebilen bir Triggers
özelliği vardır. Birkaç tetikleyici türü vardır.
Özellik Tetikleyicileri
Özellik değerlerini ayarlayan veya bir özelliğin değerine göre eylemler başlatan bir Trigger özellik tetikleyicisi olarak adlandırılır.
Özellik tetikleyicilerinin nasıl kullanılacağını göstermek için, seçilmediği sürece her ListBoxItem kısmen saydam hale getirebilirsiniz. Aşağıdaki stil, bir Opacity'in ListBoxItem değerini 0.5
olarak ayarlar. Ancak IsSelected özelliği true
olduğunda, Opacity1.0
olarak ayarlanır.
<Window.Resources>
<!-- .... other resources .... -->
<Style TargetType="ListBoxItem">
<Setter Property="Opacity" Value="0.5" />
<Setter Property="MaxHeight" Value="75" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="Opacity" Value="1.0" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Bu örnekte özellik değeri ayarlamak için bir Trigger kullanılır, ancak Trigger sınıfının tetikleyicinin eylem gerçekleştirmesini sağlayan EnterActions ve ExitActions özelliklerine de sahip olduğunu unutmayın.
MaxHeight'in ListBoxItem özelliğinin 75
olarak ayarlandığına dikkat edin. Aşağıdaki çizimde, üçüncü öğe seçili öğedir.
EventTriggers ve Storyboard'lar
Başka bir tetikleyici türü, bir olayın oluşumuna göre bir dizi eylem başlatan EventTrigger' dir. Örneğin, aşağıdaki EventTrigger nesneleri, fare işaretçisi ListBoxItemüzerine geldiğinde, MaxHeight özelliğinin 90
saniye süresince 0.2
değerine animasyonla ulaşacağını belirtir. Fare öğeden uzaklaştığında, özellik 1
saniyelik bir süre boyunca özgün değere döner.
To animasyonu için MouseLeave değeri belirtmenin gerekli olmadığını unutmayın. Bunun nedeni, animasyonun orijinal değeri izleyebilmesidir.
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="Opacity" Value="1.0" />
</Trigger.Setters>
</Trigger>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Duration="0:0:0.2"
Storyboard.TargetProperty="MaxHeight"
To="90" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Duration="0:0:1"
Storyboard.TargetProperty="MaxHeight" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
Daha fazla bilgi için bkz. Görsel Taslaklarına genel bakış.
Aşağıdaki çizimde fare üçüncü öğeyi işaret ediyor.
Çoklu Tetikleyiciler, Veri Tetikleyicileri ve Çoklu Veri Tetikleyicileri
Trigger ve EventTriggerek olarak başka tetikleyici türleri de vardır. MultiTrigger, özellik değerlerini birden çok koşula göre ayarlamanıza olanak tanır. Koşulunuzun özelliği veriye bağlı olduğunda DataTrigger ve MultiDataTrigger kullanırsınız.
Görsel Durumlar
Denetimler her zaman belirli bir durumundadır. Örneğin, fare bir denetimin yüzeyinin üzerinde hareket ettiğinde, denetimin MouseOver
ortak bir durumda olduğu kabul edilir. Belirli bir durumu olmayan bir denetimin ortak Normal
durumu içinde olduğu kabul edilir. Durumlar gruplara ayrılır ve daha önce bahsedilen durumlar CommonStates
durum grubunun bir parçasıdır. Çoğu denetimin iki durum grubu vardır: CommonStates
ve FocusStates
. Denetime uygulanan her durum grubunda, denetim her zaman CommonStates.MouseOver
ve FocusStates.Unfocused
gibi her grubun tek bir durumunda olur. Ancak, bir denetim CommonStates.Normal
ve CommonStates.Disabled
gibi aynı grup içinde iki farklı durumda olamaz. Çoğu denetimin tanıdığı ve kullandığı durumlardan oluşan bir tablo aşağıdadır.
VisualState Adı | VisualStateGroup adı | Açıklama |
---|---|---|
Normal |
CommonStates |
Varsayılan durum. |
MouseOver |
CommonStates |
Fare işaretçisi denetimin üzerine yerleştirilir. |
Pressed |
CommonStates |
Kontrol tuşuna basılır. |
Disabled |
CommonStates |
Denetim devre dışı bırakıldı. |
Focused |
FocusStates |
Kontrol odaklanmış durumda. |
Unfocused |
FocusStates |
Kontrolün odak noktası yok. |
Denetim şablonunun kök öğesinde bir System.Windows.VisualStateManager tanımlayarak, bir denetim belirli bir duruma girdiğinde animasyonları tetikleyebilirsiniz.
VisualStateManager
, hangi VisualStateGroup ve VisualState bileşimlerinin izleyebileceğinizi bildirir. Denetim izlenen duruma girdiğinde, VisualStateManager
tarafından tanımlanan animasyon başlatılır.
Örneğin, aşağıdaki XAML kodu CommonStates.MouseOver
adlı öğenin dolgu rengine animasyon eklemek için backgroundElement
durumunu izler. Denetim CommonStates.Normal
durumuna döndüğünde, backgroundElement
adlı öğenin dolgu rengi geri yüklenir.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<ColorAnimation Storyboard.TargetName="backgroundElement"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="{TemplateBinding Background}"
Duration="0:0:0.3"/>
</VisualState>
<VisualState Name="MouseOver">
<ColorAnimation Storyboard.TargetName="backgroundElement"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow"
Duration="0:0:0.3"/>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
Görsel taslaklar hakkında daha fazla bilgi için bkz. Görsel Taslaklara Genel Bakış.
Paylaşılan kaynaklar ve temalar
Tipik bir WPF uygulamasının uygulama genelinde uygulanan birden çok kullanıcı arabirimi kaynağı olabilir. Toplu olarak, bu kaynak kümesi uygulamanın teması olarak kabul edilebilir. WPF, ResourceDictionary sınıfı olarak kapsüllenmiş bir kaynak sözlüğü kullanarak ui kaynaklarını tema olarak paketleme desteği sağlar.
WPF temaları, WPF'nin herhangi bir öğenin görsellerini özelleştirmek için kullanıma sunduğu stil ve şablon oluşturma mekanizması kullanılarak tanımlanır.
WPF tema kaynakları ekli kaynak sözlüklerinde depolanır. Bu kaynak sözlükleri imzalı bir derlemeye eklenmelidir ve kodun kendisiyle aynı derlemeye veya yan yana bir derlemeye eklenebilir. PresentationFramework.dlliçin, WPF denetimlerini içeren derlemedeki tema kaynakları, bir dizi yan yana duran derlemenin içinde yer alır.
Tema, bir öğenin stilini ararken bakılması gereken son yer olur. Genellikle arama, öğe ağacına gidip uygun bir kaynağı arayarak başlar, ardından uygulama kaynak koleksiyonuna bakar ve son olarak sistemi sorgular. Bu, uygulama geliştiricilerine temaya ulaşmadan önce ağaç veya uygulama düzeyindeki herhangi bir nesnenin stilini yeniden tanımlama şansı verir.
Kaynak sözlüklerini, bir temayı birden çok uygulamada yeniden kullanmanıza olanak tanıyan tek tek dosyalar olarak tanımlayabilirsiniz. Aynı kaynak türlerini ancak farklı değerleri sağlayan birden çok kaynak sözlük tanımlayarak değiştirilebilir temalar da oluşturabilirsiniz. Bu stillerin veya diğer kaynakların uygulama düzeyinde yeniden tanımlanması, bir uygulamanın dış görünümünün belirlenmesi için önerilen yaklaşımdır.
Stiller ve şablonlar da dahil olmak üzere bir dizi kaynağı uygulamalar arasında paylaşmak için bir XAML dosyası oluşturabilir ve ResourceDictionary dosyasına başvuru içeren bir shared.xaml
tanımlayabilirsiniz.
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Shared.xaml" />
</ResourceDictionary.MergedDictionaries>
shared.xaml
paylaşımının kendisinin, stil ve fırça kaynakları kümesi içeren bir ResourceDictionary tanımlaması ve bu paylaşımın, bir uygulamadaki denetimlerin tutarlı bir görünüme sahip olmasını sağlamasıdır.
Daha fazla bilgi için bkz. Birleştirilmiş kaynak sözlükleri.
Özel denetiminiz için bir tema oluşturuyorsanız, Denetimi Yazmaya Genel Bakışbölümünün Tema Düzeyinde Kaynak Tanımlama kısmına bakın.
Ayrıca bakınız
.NET Desktop feedback