C# XAML如何根据参数值应用样式
目标是检查参数的状态,每个参数的状态可以采用枚举值(锁定、解锁或值不正确)。显示器 将根据参数的状态而有所不同(例如,锁定矩形将为红色,解锁文本将为粗体,默认文本将为灰色) 例如,在主类中,我们有不同的参数VarA、VarB和VarC。每个参数的状态可以不同 枚举状态{锁定,解锁,值不正确}C# XAML如何根据参数值应用样式,c#,xaml,C#,Xaml,目标是检查参数的状态,每个参数的状态可以采用枚举值(锁定、解锁或值不正确)。显示器 将根据参数的状态而有所不同(例如,锁定矩形将为红色,解锁文本将为粗体,默认文本将为灰色) 例如,在主类中,我们有不同的参数VarA、VarB和VarC。每个参数的状态可以不同 枚举状态{锁定,解锁,值不正确} State VarA = lock State VarB = unlock State VarC = lock 在我使用这个样式和基于这个样式的矩形之前,当我按下一个按钮时,样式会改变,但是对所有参数的反
State VarA = lock
State VarB = unlock
State VarC = lock
在我使用这个样式和基于这个样式的矩形之前,当我按下一个按钮时,样式会改变,但是对所有参数的反应都是一样的
<Style x:Key="DisplayLockGroup" TargetType="GroupBox">
<Setter Property="BorderThickness" Value="2"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Source={x:Static local:LockMgt.Instance}, Path=isLocked}" Value="true">
<Setter Property="BorderBrush" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Source={x:Static local:LockMgt.Instance}, Path=isLocked}" Value="false">
<Setter Property="BorderBrush" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
<Rectangle x:Name="r_LockEcuTypes" Grid.Row="5" Grid.RowSpan="3" Grid.Column ="1" Grid.ColumnSpan="7" Style="{DynamicResource DisplayLockRectangleGroup}" />
现在我想改变这个行为,我有不同的参数,我想单独检查这个参数的状态,并根据值应用一种样式,但我不知道如何才能做到
例如,对于一个参数:
State VarA=lock=>i
要应用样式1
State VarB=unlock=>i
要应用样式2
State VarC=lock=>i
希望应用样式1,但如果值从lock更改为unlock,我希望应用样式2
我不知道如何创建XAML以正确显示预期内容 可以在XAML绑定中应用枚举到颜色转换器
Background="{Binding Source=StateValue,
Converter={StaticResource stateValueColorConverter}}"
您可以很容易地找到详细的文档:这是为了让您了解使用的主要内容。您可以在XAML绑定中应用枚举到颜色转换器
Background="{Binding Source=StateValue,
Converter={StaticResource stateValueColorConverter}}"
您可以很容易地找到详细的文档:这是为了让您了解使用的主要内容。如前所述,根据您的实际需要,您有几种选择
状态
转换为某个属性值Style.Triggers
更改属性(与当前方法类似)ControlTemplate.Triggers
交换内部样式rect1
、rect2
和rect3
,表示具有相同编号的方法)和一个按钮,该按钮负责更改ViewModel对象的状态,以显示每个矩形的反应方式
XAML
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525"
Loaded="Window_Loaded">
<Window.Resources>
<!-- Used for 1. -->
<local:StateToBorderBrushConverter x:Key="stateConverter"/>
<!-- Used for 2. -->
<Style x:Key="DisplayLockGroup" TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="2"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.locked}">
<Setter Property="Stroke" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.unlock}">
<Setter Property="Stroke" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
<!-- Used for 3. -->
<Style x:Key="DefaultRectangleStyle" TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="2"/>
</Style>
<Style x:Key="LockedRectangleStyle" TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="Red" />
</Style>
<Style x:Key="UnlockedRectangleStyle" TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="Green" />
</Style>
</Window.Resources>
<Grid x:Name="grid1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle x:Name="rect1" Grid.Row="0" Margin="5" StrokeThickness="2" Stroke="{Binding Data1State,Converter={StaticResource stateConverter}}" />
<Rectangle x:Name="rect2" Grid.Row="1" Margin="5" Style="{StaticResource DisplayLockGroup}" />
<ContentControl Margin="5" Grid.Row="2">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<Rectangle x:Name="rect3" Style="{StaticResource DefaultRectangleStyle}" />
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.locked}">
<Setter TargetName="rect3" Property="Style" Value="{StaticResource LockedRectangleStyle}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.unlock}">
<Setter TargetName="rect3" Property="Style" Value="{StaticResource UnlockedRectangleStyle}"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
<Button x:Name="ChangeStateButton" Grid.Row="3" Margin="5" VerticalAlignment="Center" Content="Change State" Click="ChangeStateButton_Click"/>
</Grid>
</Window>
利与弊:
如果在许多不同的控件类型中针对相同的属性类型,则转换器方法非常有用。转换器正在返回一个画笔,它不关心该画笔是否将用于矩形.Stroke
、边框.BorderBrush
或其他上下文中
样式触发器方法对于目标控件类型的灵活性较低,但更容易根据状态维护多个属性的更改
控制模板触发器方法在某些高级场景中很有用。它允许为每个状态分别定义样式。但是,我只建议您使用附加功能派生自己的自定义控件,而不是仅用于切换样式的特殊控件模板
如前所述,根据您的实际需要,您有几个选项
将状态
转换为某个属性值
通过Style.Triggers
更改属性(与当前方法类似)
包装控件并通过包装控件上的ControlTemplate.Triggers
交换内部样式
下面的示例显示了三个矩形(rect1
、rect2
和rect3
,表示具有相同编号的方法)和一个按钮,该按钮负责更改ViewModel对象的状态,以显示每个矩形的反应方式
XAML
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525"
Loaded="Window_Loaded">
<Window.Resources>
<!-- Used for 1. -->
<local:StateToBorderBrushConverter x:Key="stateConverter"/>
<!-- Used for 2. -->
<Style x:Key="DisplayLockGroup" TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="2"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.locked}">
<Setter Property="Stroke" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.unlock}">
<Setter Property="Stroke" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
<!-- Used for 3. -->
<Style x:Key="DefaultRectangleStyle" TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="2"/>
</Style>
<Style x:Key="LockedRectangleStyle" TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="Red" />
</Style>
<Style x:Key="UnlockedRectangleStyle" TargetType="Rectangle">
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="Green" />
</Style>
</Window.Resources>
<Grid x:Name="grid1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle x:Name="rect1" Grid.Row="0" Margin="5" StrokeThickness="2" Stroke="{Binding Data1State,Converter={StaticResource stateConverter}}" />
<Rectangle x:Name="rect2" Grid.Row="1" Margin="5" Style="{StaticResource DisplayLockGroup}" />
<ContentControl Margin="5" Grid.Row="2">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<Rectangle x:Name="rect3" Style="{StaticResource DefaultRectangleStyle}" />
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.locked}">
<Setter TargetName="rect3" Property="Style" Value="{StaticResource LockedRectangleStyle}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.unlock}">
<Setter TargetName="rect3" Property="Style" Value="{StaticResource UnlockedRectangleStyle}"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
<Button x:Name="ChangeStateButton" Grid.Row="3" Margin="5" VerticalAlignment="Center" Content="Change State" Click="ChangeStateButton_Click"/>
</Grid>
</Window>
利与弊:
如果在许多不同的控件类型中针对相同的属性类型,则转换器方法非常有用。转换器正在返回一个画笔,它不关心该画笔是否将用于矩形.Stroke
、边框.BorderBrush
或其他上下文中
样式触发器方法对于目标控件类型的灵活性较低,但更容易根据状态维护多个属性的更改
控制模板触发器方法在某些高级场景中很有用。它允许为每个状态分别定义样式。但是,我只建议您使用附加功能派生自己的自定义控件,而不是仅用于切换样式的特殊控件模板
多亏了grek40,这正是我想要的。我尝试了选项3和2,效果很好,我使用了案例2,它最容易实现。
我在锁定和解锁状态下添加图像时使用了相同的行为。多亏了grek40,这正是我想要的。我尝试了选项3和2,效果很好,我使用了案例2,它最容易实现。
在锁定和解锁状态下添加图像时,我使用了相同的行为。在Xaml.cs文件中,我如何访问您提案中的参数rect3,当我尝试时,我有编译错误“名称“rect3”在当前视图中不存在,我已编写
XAML.CS:
rect3.Visibility = Visibility.Collapsed;
XAML:
<ContentControl Grid.RowSpan="3" Grid.ColumnSpan="3" KeyboardNavigation.IsTabStop="False">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<Rectangle x:Name="rect3" Style="{StaticResource DefaultRectangleStyle}" />
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.locked}">
<Setter TargetName="rect3" Property="Style" Value="{StaticResource LockedRectangleStyle}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Data1State}" Value="{x:Static local:State.unlock}">
<Setter TargetName="rect3" Property="Style" Value="{StaticResource UnlockedRectangleStyle}"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
在Xaml.cs文件中,我如何访问您提案中的参数rect3,当我尝试它时,我有编译错误“名称“rect3”在当前视图中不存在,我有