C# XAML如何根据参数值应用样式

C# XAML如何根据参数值应用样式,c#,xaml,C#,Xaml,目标是检查参数的状态,每个参数的状态可以采用枚举值(锁定、解锁或值不正确)。显示器 将根据参数的状态而有所不同(例如,锁定矩形将为红色,解锁文本将为粗体,默认文本将为灰色) 例如,在主类中,我们有不同的参数VarA、VarB和VarC。每个参数的状态可以不同 枚举状态{锁定,解锁,值不正确} State VarA = lock State VarB = unlock State VarC = lock 在我使用这个样式和基于这个样式的矩形之前,当我按下一个按钮时,样式会改变,但是对所有参数的反

目标是检查参数的状态,每个参数的状态可以采用枚举值(锁定、解锁或值不正确)。显示器 将根据参数的状态而有所不同(例如,锁定矩形将为红色,解锁文本将为粗体,默认文本将为灰色)

例如,在主类中,我们有不同的参数VarA、VarB和VarC。每个参数的状态可以不同

枚举状态{锁定,解锁,值不正确}

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”在当前视图中不存在,我有