如何将属性传递给WPF样式
我正在尝试为WPF ItemContainerStyle编写一个可重用的模板 此模板更改TabControl项的外观。 此模板用于应用程序中的多个位置 在使用它的每个地方,我希望能够向它传递不同的参数。 例如:要更改项目边框的边距,请执行以下操作:如何将属性传递给WPF样式,wpf,Wpf,我正在尝试为WPF ItemContainerStyle编写一个可重用的模板 此模板更改TabControl项的外观。 此模板用于应用程序中的多个位置 在使用它的每个地方,我希望能够向它传递不同的参数。 例如:要更改项目边框的边距,请执行以下操作: <Style x:Key="TabItemStyle1" TargetType="{x:Type TabItem}"> <Setter Property="Margin" Value="10
<Style x:Key="TabItemStyle1" TargetType="{x:Type TabItem}">
<Setter Property="Margin" Value="10,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd" Width="80"
Background="Gray"
Margin="{TemplateBinding Margin}">
<ContentPresenter x:Name="Content"
ContentSource="Header" />
</Border>
</Grid>
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
...
<TabControl ItemContainerStyle="{DynamicResource TabItemStyle1}">
或
其动机是在不同的地方使用此模板,并具有不同的边距。
有办法做到这一点吗
谢谢解决此问题的一种方法是向要显示的对象/视图模型添加边距特性,并(数据)绑定到模板中的该值
据我所知,不支持参数化样式/模板 您可以使用附加属性执行此操作。我写了一篇博文解释如何做到这一点:
另一个选项是使用
DynamicResource
,并在派生样式中重新定义资源好的,我在dave的帮助下找到了一种方法
解决方案是创建派生模板并在其中设置属性。
这样可以重用原始模板
<Style x:Key="TabItemStyle2" TargetType="{x:Type TabItem}"
BasedOn="{StaticResource TabItemStyle1}">
<Style.Setters>
<Setter Property="Margin" Value="40,0"></Setter>
</Style.Setters>
</Style>
并将TabControl的ItemContainerStyle设置为派生样式:
<TabControl ItemContainerStyle="{DynamicResource TabItemStyle2}">
在我的例子中,我必须更改应用模板中的一些参数(因此我不能只使用setter)。 我不想编写一些遍历可视化树或注册附加属性的类来进行更改 但是,可以在基础样式中定义资源,并在派生定义中重写这些值。因此,在最初的示例中,这将如下所示:
<Style x:Key="AbsTabItemStyle" TargetType="{x:Type TabItem}">
<!-- Override these default values in derived style definitions -->
<Style.Resources>
<s:Double x:Key="GridBorderMargin">10</s:Double>
<Color x:Key="GridBorderColor">Grey</Color>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd"
Width="80"
Background="{DynamicResouces GridBorderColor}"
Margin="{DynamicResouces GridBorderMargin}"
>
<ContentPresenter x:Name="Content"
ContentSource="Header" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BigMarginTabItemStyle" TargetType="{x:Type TabItem}" BasedOn="{StaticResource AbsTabItemStyle}">
<!-- Set different values in this derived style definition -->
<Style.Resources>
<s:Double x:Key="GridBorderMargin">20</s:Double>
</Style.Resources>
</Style>
<Style x:Key="RedTabItemStyle" TargetType="{x:Type TabItem}" BasedOn="{StaticResource AbsTabItemStyle}">
<!-- Set different values in this derived style definition -->
<Style.Resources>
<c:Color x:Key="GridBorderColor">Red</Color>
</Style.Resources>
</Style>
10
灰色
20
红色
谢谢Thomas,您的第一个答案清晰而优雅,但我想找到一种不用编写任何额外C#代码的方法。我上面的答案是这样的,但是再一次——编写一个小的静态类并不是什么大问题,它可能更优雅。谢谢。顺便说一下,我的答案(上面)使用了静态属性。
<TabControl ItemContainerStyle="{DynamicResource TabItemStyle2}">
<Style x:Key="AbsTabItemStyle" TargetType="{x:Type TabItem}">
<!-- Override these default values in derived style definitions -->
<Style.Resources>
<s:Double x:Key="GridBorderMargin">10</s:Double>
<Color x:Key="GridBorderColor">Grey</Color>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd"
Width="80"
Background="{DynamicResouces GridBorderColor}"
Margin="{DynamicResouces GridBorderMargin}"
>
<ContentPresenter x:Name="Content"
ContentSource="Header" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BigMarginTabItemStyle" TargetType="{x:Type TabItem}" BasedOn="{StaticResource AbsTabItemStyle}">
<!-- Set different values in this derived style definition -->
<Style.Resources>
<s:Double x:Key="GridBorderMargin">20</s:Double>
</Style.Resources>
</Style>
<Style x:Key="RedTabItemStyle" TargetType="{x:Type TabItem}" BasedOn="{StaticResource AbsTabItemStyle}">
<!-- Set different values in this derived style definition -->
<Style.Resources>
<c:Color x:Key="GridBorderColor">Red</Color>
</Style.Resources>
</Style>