代码之家  ›  专栏  ›  技术社区  ›  Konstantin Spirin

如何参数化WPF样式?

  •  1
  • Konstantin Spirin  · 技术社区  · 16 年前

    我正在寻找一种最简单的方法来消除WPF代码中的重复。

    下面的代码是一个带有3个灯的简单交通灯- Red , Amber , Green . 它绑定到具有一个枚举属性的ViewModel State 取这三个值中的一个。

    声明3个省略号的代码非常重复。现在我想添加动画,这样每一个光淡入淡出样式将变得更大,复制将恶化。

    可以用参数化样式吗 状态 Color 我可以在描述一个光的行为的资源中有一个单一的样式,然后使用它3次-对于“红色”、“琥珀色”和“绿色”灯?

    <UserControl.Resources>
        <l:TrafficLightViewModel x:Key="ViewModel" />
    </UserControl.Resources>
    
    <StackPanel Orientation="Vertical" DataContext="{StaticResource ViewModel}">
        <StackPanel.Resources>
            <Style x:Key="singleLightStyle" TargetType="{x:Type Ellipse}">
                <Setter Property="StrokeThickness" Value="2" />
                <Setter Property="Stroke" Value="Black" />
                <Setter Property="Height" Value="{Binding Width, RelativeSource={RelativeSource Self}}" />
                <Setter Property="Width" Value="60" />
                <Setter Property="Fill" Value="LightGray" />
            </Style>
        </StackPanel.Resources>
    
        <Ellipse>
            <Ellipse.Style>
                <Style TargetType="{x:Type Ellipse}" BasedOn="{StaticResource singleLightStyle}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding State}" Value="Red">
                            <Setter Property="Fill" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Ellipse.Style>
        </Ellipse>
        <Ellipse>
            <Ellipse.Style>
                <Style TargetType="{x:Type Ellipse}" BasedOn="{StaticResource singleLightStyle}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding State}" Value="Amber">
                            <Setter Property="Fill" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Ellipse.Style>
        </Ellipse>
        <Ellipse>
            <Ellipse.Style>
                <Style TargetType="{x:Type Ellipse}" BasedOn="{StaticResource singleLightStyle}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding State}" Value="Green">
                            <Setter Property="Fill" Value="Green" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Ellipse.Style>
        </Ellipse>
    </StackPanel>
    

    1 回复  |  直到 16 年前
        1
  •  1
  •   Ben Von Handorf    16 年前

    只要你的“红绿灯”被包裹在一个控制装置里,它看起来就是,我不认为这是可怕的。每个椭圆都有很好的定义,并且有不同的触发器,每个都指示自己的状态。您已经将常见部分分解成基本样式,这很好。

    您可以将单个省略号包装在另一个具有 ActiveState 属性与AN ActiveFill 属性。然后你的交通灯看起来像:

    <StackPanel Orientation="Vertical" DataContext="{StaticResource ViewModel}">
        <my:Indicator State="{Binding State}" ActiveState="Red" ActiveFill="Red" />
        <my:Indicator State="{Binding State}" ActiveState="Amber" ActiveFill="Red" />
        <my:Indicator State="{Binding State}" ActiveState="Green" ActiveFill="Green" />
    </StackPanel>
    

    这样可以将所有椭圆样式都包含在指示器控件中,控件唯一需要担心的是比较 State 激活物 确定它是否应该用 活性填料 刷子。

    至于这是否值得付出努力,这取决于你漂浮在这些物体中的多少,以及你是否在红绿灯用户控制之外使用它们。记住:你不需要它。