Jeśli mam dwa 200-liniowe szablony kontrolne, które różnią się tylko kilkoma słowami (kilka kolorów), w jaki sposób mogę dokonać ponownego użycia Xaml? Oznacza to, że nie trzeba kopiować i wklejać szablonu oraz zmieniać 3 słów w 200 liniach.Sparametryzowany styl/szablon w WPF?
Oto uproszczony przykład. Jedyna różnica między tymi dwoma stylami to kolor obramowania. Czy mogę w jakiś sposób zdefiniować ButtonStyle z sparametryzowanym kolorem i odziedziczyć z niego BlackButtonStyle i GrayButtonStyle i określić tylko ten kolor w BlackButtonStyle i GrayButtonStyle?
alt text http://img444.imageshack.us/img444/9545/buttonstyles.png
<Window x:Class="WpfApplication33.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="BlackButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Black" BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="GrayButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Gray" BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Black Button"
Style="{StaticResource BlackButtonStyle}"/>
<Button Content="Gray Button"
Style="{StaticResource GrayButtonStyle}"/>
</StackPanel>
</Window>
Oto kod oparty na 2 odpowiedzi. styl musi jedynie być ustawiony na kontrolę, ale niestety nadal bałagan znacznika kontroli:
<Window x:Class="WpfApplication33.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="border"
BorderBrush="Black"
BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Tag" Value="Gray">
<Setter TargetName="border"
Property="BorderBrush"
Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BlackButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonStyle}"/>
<Style x:Key="GrayButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonStyle}">
<Setter Property="Tag" Value="Gray"/>
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Black Button"
Style="{StaticResource BlackButtonStyle}"/>
<Button Content="Gray Button"
Style="{StaticResource GrayButtonStyle}"/>
</StackPanel>
</Window>
Tak, też o tym myślałem, ale nie działa to w przypadku standardowych elementów sterujących, np. Przycisku, jeśli chcę uniknąć używania tagu. Będę musiał zmienić wszystkie moje przyciski na niestandardowe sterowanie. Dodatkowo wielokrotne określanie tej samej pary (tagu, stylu) jest nadal zduplikowanym kodem, ale o wiele mniej niż początkowo. –
Można łatwo utworzyć kontrolkę UserControl, która hermetyzuje to wszystko i zapewnia DependencyProperty, aby ustawić kolor. Wtedy nie miałbyś powielonego kodu. Ale nie można uniknąć tworzenia oddzielnego elementu do przechowywania dodatkowych danych. – Charlie