Параметризованный стиль / шаблон в WPF? - PullRequest
10 голосов
/ 06 августа 2010

Если у меня есть два шаблона управления длиной 200 строк, которые отличаются только несколькими словами (несколькими цветами), как я могу сделать XAML многоразовым?То есть не нужно копировать-вставлять шаблон и менять 3 слова в 200 строк.

Вот упрощенный пример.Единственная разница между этими двумя стилями - цвет границы.Поэтому можно ли как-то определить ButtonStyle с параметризованным цветом и наследовать от него BlackButtonStyle и GrayButtonStyle и указать только этот цвет в BlackButtonStyle и 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>

Вот код, основанный на 2 ответах.На элементе управления должен быть установлен только стиль, но, к сожалению, он все еще портит тег элемента управления:

<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>

Ответы [ 3 ]

5 голосов
/ 06 августа 2010

Правильный путь для этого обычно заключается в создании DependencyProperty в классе, который может содержать параметризованные данные, и затем привязке к этому свойству в вашем шаблоне. Для создания быстрого примера я собираюсь использовать свойство Button.Tag, которое отлично подходит для хранения чего-то простого, например кисти:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Window1" Height="300" Width="300">
<Page.Resources>
    <SolidColorBrush x:Key="BlackBrush" Color="Black"/>
    <SolidColorBrush x:Key="GrayBrush" Color="Gray"/>
    <Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border BorderBrush="{TemplateBinding Tag}" BorderThickness="3">
                        <ContentControl Content="{TemplateBinding Content}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

<StackPanel>
    <Button Content="Black Button" Tag="{StaticResource BlackBrush}"
            Style="{StaticResource CustomButtonStyle}"/>
    <Button Content="Gray Button" Tag="{StaticResource GrayBrush}"
            Style="{StaticResource CustomButtonStyle}"/>
</StackPanel>

4 голосов
/ 06 августа 2010

Хотя Чарли прав в своем примере, для вашего конкретного случая я бы просто использовал свойства BorderThickness и BorderBrush, которые уже доступны кнопке: вы можете использовать {TemplateBinding BorderBrush} вместо создания собственного свойства.

Изменить: образец xaml ... обратите внимание, что мой стиль по умолчанию цвет и толщина, но они могут быть переопределены встроенным ...

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Window1" Height="300" Width="300">
<Page.Resources>
    <SolidColorBrush x:Key="BlackBrush" Color="Black"/>
    <SolidColorBrush x:Key="GrayBrush" Color="Gray"/>
    <Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="BorderThickness" Value="3" />
        <Setter Property="BorderBrush" Value="{StaticResource BlackBrush}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderColor="{TemplateBinding BorderThickness}">
                        <ContentControl Content="{TemplateBinding Content}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

<StackPanel>
    <Button Content="Black Button" BorderBrush="{StaticResource BlackBrush}"
            Style="{StaticResource CustomButtonStyle}"/>
    <Button Content="Gray Button" BorderBrush="{StaticResource GrayBrush}"
            Style="{StaticResource CustomButtonStyle}"/>
</StackPanel>
3 голосов
/ 08 октября 2011

Взгляните на это решение , оно решает именно вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...