1

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

下面的代码是一个简单的红绿灯,有 3 个灯 - Red, Amber, Green。它绑定到具有一个枚举属性的 ViewModel,该属性State采用这 3 个值之一。

声明 3 个省略号的代码非常重复。现在我想添加动画,让每个灯光都淡入淡出——样式会变得更大,重复会更糟。

是否可以使用StateColor参数对样式进行参数化,以便我可以在描述灯光行为的资源中使用单一样式,然后使用它 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>

4

1 回答 1

1

只要您的“交通灯”被包裹在一个控件中,它看起来就是这样,我认为这并不可怕。每个椭圆都有很好的定义,并且有不同的触发器,每个都表示它自己的状态。您已经将通用部分考虑到了基本样式中,这很好。

ActiveState您可以将单个省略号包装在另一个具有属性和属性的用户控件(不需要支持 ViewModel)中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>

这使您可以将所有 Ellipse 样式封装在 Indicator 控件中,控件唯一需要担心的是将 与 进行比较StateActiveState确定它是否应该用ActiveFill画笔填充自己。

至于这是否值得付出努力,这取决于您有多少漂浮在周围,以及您是否在交通灯用户控制之外使用它们。记住:你不需要它。

于 2010-03-17T12:34:23.987 回答