WPFのスタイルをパラメータにする方法?
-
20-09-2019 - |
質問
私はWPFのコードで重複を除去する最も簡単な方法を探しています。
Red
、Amber
、Green
- 以下のコードは、3ライトが付いている簡単な交通光です。それは、これらの3つの値のいずれかを取って1列挙型プロパティState
を持っているのViewModelにバインドされます。
3つの楕円を宣言するコードは非常に重複です。今私は、それぞれの光が中とフェードアウトするようにアニメーションを追加したい - 。スタイルがさらに大きくなり、重複が悪化します。
「赤」、「アンバー」と「グリーンライトのために -それは私が光の挙動を記述するリソースに単一のスタイルを持っているし、それを3回使用できるようにState
とColor
引数を指定してスタイルをパラメータすることは可能ですか?
<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>
解決
限り、あなたの「トラフィックライトが」それは表示されたコントロール、内側に包まれているように、私はこれは恐ろしいではないと思います。各楕円は、よく定義され、異なるトリガを有し、それぞれがそれ自身の状態を示します。あなたはすでに良いです基本スタイル、に共通の部品を因数分解しました。
あなたはActiveState
プロパティとActiveFill
プロパティを持っていた(バッキングのViewModelを必要としない)別のユーザーコントロール内の個々の楕円をラップすることができます。次に、あなたのTrafficLightは、次のようになります。
<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
ブラシで自身を埋める必要があるかどうかを判断するためにActiveState
にActiveFill
を比較している心配する必要性を制御する唯一の内側にすべてのあなたの楕円のスタイリングを包むことができます。
これは努力のかいないの価値がある場合については、それはあなたが漂ってきたこれらの何に依存して、あなたのトラフィックライトユーザーコントロールの外にそれらを使用する場合。覚えている:あなたはゴナないですそれを必要とする
。