我正在尝试为WPF ItemContainerStyle编写可重用的模板。
此模板更改TabControl项目的外观。 此模板旨在用于应用程序中的多个位置。
在每个地方使用它我希望能够传递不同的参数。 例如:更改项目边框的边距:
<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}">
在使用样式的地方,我想写下这样的内容:
ItemContainerStyle="{DynamicResource TabItemStyle1 Margin='5,0'}"
或
<TabControl Margin="78,51,167,90" ItemContainerStyle="{DynamicResource TabItemStyle1}"
ItemContainerStyle.Margin="5,0">
动机是在具有不同边距的不同位置使用此模板。 有没有办法做到这一点?
谢谢
答案 0 :(得分:5)
您可以使用附加属性来执行此操作。我写了一篇博文,解释了如何做到这一点:
http://www.thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/
另一种选择是使用DynamicResource
,并在派生样式中重新定义资源
答案 1 :(得分:4)
在我的情况下,我不得不在应用模板的深处更改一些参数(所以我不能只使用一个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>
答案 2 :(得分:2)
好的,我已经找到了一种方法,在戴夫的帮助下做到这一点。
解决方案是创建派生模板并在其中设置属性。 这样可以重复使用原始模板。
<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}">
答案 3 :(得分:1)
在TemplateBinding上搜索将数据传递给模板的术语。
这是一篇解释它的帖子,可以帮助您入门。 http://devlicio.us/blogs/christopher_bennage/archive/2008/07/04/templatebinding-a-bridge-between-styles-and-templates.aspx
答案 4 :(得分:0)
解决问题的方法是向要显示的对象/ ViewModel添加Margin属性,并将(数据)绑定到模板中的该值。
据我所知,不支持参数化样式/模板。