2

我正在尝试为 WPF ItemContainerStyle 编写一个可重用的模板。

这个模板改变了 TabControl 的 Item 的外观。此模板旨在用于应用程序中的多个位置。

在每个使用它的地方,我希望能够向它传递不同的参数。例如:要更改项目的边框的边距:

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

动机是在具有不同边距的不同地方使用此模板。有没有办法做到这一点 ?

谢谢

4

4 回答 4

6

您可以使用附加的属性来做到这一点。我写了一篇博客文章解释了如何做到这一点:

http://www.thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/

另一种选择是使用DynamicResource和重新定义派生样式中的资源

于 2012-05-08T03:16:18.223 回答
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>
于 2014-06-02T09:10:04.227 回答
3

好的,在戴夫的帮助下,我找到了一种方法。

解决方案是创建一个派生模板并在其中设置属性。这样可以重复使用原始模板。

<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}">
于 2012-05-08T03:16:20.157 回答
0

解决它的一种方法是向要显示的对象/ViewModel 添加一个 Margin 属性,并(数据)绑定到模板中的该值。

据我所知,不支持参数化样式/模板。

于 2012-05-07T12:23:03.467 回答