WPF中的参数化样式/模板?

Csu*_*enő 10 wpf

如果我有两个200行长的控制模板,只有几个字(几种颜色)不同,我怎样才能使xaml可重用?也就是说,不必复制粘贴模板并在200行中更改3个单词.

这是一个简化的例子.两种风格的唯一区别是边框颜色.那么我能以某种方式定义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>
Run Code Online (Sandbox Code Playgroud)

这是基于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>
Run Code Online (Sandbox Code Playgroud)

Cha*_*lie 5

正确的解决方法通常是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>
Run Code Online (Sandbox Code Playgroud)


Dan*_*zey 5

虽然查理对他的例子是正确的,但对于你的具体情况,我只会使用按钮已经公开的BorderThicknessBorderBrush属性:你可以使用{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>
Run Code Online (Sandbox Code Playgroud)