Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将属性传递给WPF样式_Wpf - Fatal编程技术网

如何将属性传递给WPF样式

如何将属性传递给WPF样式,wpf,Wpf,我正在尝试为WPF ItemContainerStyle编写一个可重用的模板 此模板更改TabControl项的外观。 此模板用于应用程序中的多个位置 在使用它的每个地方,我希望能够向它传递不同的参数。 例如:要更改项目边框的边距,请执行以下操作: <Style x:Key="TabItemStyle1" TargetType="{x:Type TabItem}"> <Setter Property="Margin" Value="10

我正在尝试为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}">


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


谢谢

解决此问题的一种方法是向要显示的对象/视图模型添加边距特性,并(数据)绑定到模板中的该值


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

您可以使用附加属性执行此操作。我写了一篇博文解释如何做到这一点:


另一个选项是使用
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>