WPF中的参数化样式/模板?
如果我有两个200行长的控件模板,它们只在几个字(一些颜色)上有所不同,那么如何使xaml可重用?也就是说,不必复制粘贴模板并在200行中更改3个单词 这里是一个简化的例子。这两种样式之间的唯一区别是边框颜色。那么,我可以用参数化的颜色定义一个ButtonStyle,并从中继承BlackButtonStyle和GrayButtonStyle,并在BlackButtonStyle和GrayButtonStyle中仅指定该颜色吗WPF中的参数化样式/模板?,wpf,Wpf,如果我有两个200行长的控件模板,它们只在几个字(一些颜色)上有所不同,那么如何使xaml可重用?也就是说,不必复制粘贴模板并在200行中更改3个单词 这里是一个简化的例子。这两种样式之间的唯一区别是边框颜色。那么,我可以用参数化的颜色定义一个ButtonStyle,并从中继承BlackButtonStyle和GrayButtonStyle,并在BlackButtonStyle和GrayButtonStyle中仅指定该颜色吗 下面是基于这两个答案的代码。只需在控件上设置样式,但不幸的是,
下面是基于这两个答案的代码。只需在控件上设置样式,但不幸的是,它仍然会弄乱控件的标记:
<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>
正确的方法通常是在可以保存参数化数据的类上创建一个
dependencProperty
,然后绑定到模板中的该属性。为了创建一个快速示例,我将使用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>
虽然Charlie的例子是对的,但对于您的具体情况,我只会使用按钮已经公开的
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>
看一看,它解决了您面临的确切问题。我很难将其可视化,尽管这听起来是最好的解决方案。你能解释一下这在代码中是什么样子吗?@Berryl:看我的编辑。它和Charlie的没有太大区别,我只是使用已经存在的属性。特别要注意的是,你可以在样式中定义一个默认值,所有的按钮都会选择。是的,很酷。如果这是我的问题,我会把它作为答案!谢谢,我也这么想,但是如果我想避免使用标签,它对标准控件(即按钮)不起作用。我需要将所有按钮更改为自定义控件。此外,多次指定相同的(标记、样式)对仍然是重复的代码,但比最初的代码要少很多。您可以轻松创建一个UserControl,封装所有这些内容,并提供DependencyProperty来设置颜色。这样就不会有重复的代码。但是,您不能避免创建某种单独的实体来存储额外的数据。
<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>