在DataTriggers中重用ControlTemplate

时间:2015-05-26 15:37:53

标签: c# wpf

我正在使用WPF 4.0来开发窗口,并希望在我的资源中重用ControlTemplate以用于各种Label控件。

我使用ControlTemplate定义通用基本标签样式,然后定义派生标签样式以控制颜色和标签文本。

然后我根据属性值将这些样式应用于数据触发器。

到目前为止我尝试过抛出一个IllegalArgument异常:'不允许Style对象影响它所适用的对象的Style属性'。

有没有一种有效的方法可以做到这一点?

这是我到目前为止产生异常的原因:

<Style x:Key="BaseLabelStyle" TargetType="{x:Type Label}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid Background="{TemplateBinding Background}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="24"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="24"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="1"
                               VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                               HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                               Padding="{TemplateBinding Padding}"
                               Background="{TemplateBinding Background}"
                               Foreground="{TemplateBinding Foreground}"
                               Width="{TemplateBinding Width}"
                               Height="{TemplateBinding Height}"
                           />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="AvailableLabelStyle" TargetType="{x:Type Label}" BasedOn="{StaticResource BaseLabelStyle}">
    <Style.Resources>
        <Style>
            <Setter Property="Label.Background" Value="#FF567E4A"/>
            <Setter Property="Label.Foreground" Value="White"/>
            <Setter Property="TextBlock.Text" Value="Available"/>
        </Style>
    </Style.Resources>
</Style>

我想扩展派生样式以定义其他颜色和标签文本更改。

这个派生的样式在这里应用:

<Label x:Name="Avail_Out_LBL" 
       HorizontalAlignment="Left" Margin="111,44,0,0"
       VerticalAlignment="Top" Width="124" Height="18" 
       VerticalContentAlignment="Center"
       HorizontalContentAlignment="Center" SnapsToDevicePixels="False" 
       Grid.Column="1" Padding="0">
    <Label.Style>
        <Style TargetType="{x:Type Label}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding MonitorAndControlData.Availability}" Value="Available">
                    <Setter Property="Style" Value="{StaticResource AvailableLabelStyle}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
</Label>

异常指向Label中的结束/ DataTrigger。我无法判断问题是在Style的使用中还是在资源中的顶部定义中。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

问题在于您正试图从样式中更改样式,这是不允许的。

在您的情况下我会做的是为您的标签创建一个自定义UserControl,如下所示:

<UserControl ...>
    <UserControl.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Grid Background="{TemplateBinding Background}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="24"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="24"/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Column="1" 
                                       VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                       HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                       Padding="{TemplateBinding Padding}"
                                       Background="{TemplateBinding Background}"
                                       Foreground="{TemplateBinding Foreground}"
                                       Width="{TemplateBinding Width}"
                                       Height="{TemplateBinding Height}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <DataTrigger Binding="{Binding Availability, RelativeSource={RelativeSource AncestorType={x:Type theTypeOfYourControl}}}" Value="Available">
                                <Setter Property="Label.Background" Value="#FF567E4A"/>
                                <Setter Property="Label.Foreground" Value="White"/>
                                <Setter Property="TextBlock.Text" Value="Available"/>             
                            </DataTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Label x:Name="Avail_Out_LBL" 
           HorizontalAlignment="Left" Margin="111,44,0,0"
           VerticalAlignment="Top" Width="124" Height="18" 
           VerticalContentAlignment="Center"
           HorizontalContentAlignment="Center" SnapsToDevicePixels="False" 
           Grid.Column="1" Padding="0"/>
</UserControl>

触发器中的setter可能不好,你必须定位正确的属性才能使它工作。此外,您需要创建一个名为Availability的依赖项属性或任何其他相关名称(我只是在绑定中使用了该名称)以在UserControl之外公开它。使用UserControl时,您需要绑定到此DependencyProperty。

以下是有关如何操作的一些链接,其中包含更多内容:

http://www.codeproject.com/Articles/32825/How-to-Creating-a-WPF-User-Control-using-it-in-a-W

http://www.wpftutorial.net/dependencyproperties.html