我正在使用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的使用中还是在资源中的顶部定义中。
非常感谢任何帮助。
答案 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