2010-03-17 28 views
1

我正在尋找一種最簡單的方法來刪除我的WPF代碼中的重複。如何參數化WPF風格?

下面的代碼是一個簡單的3燈交通燈 - RedAmberGreen。它綁定到一個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> 

回答

1

只要你的「紅綠燈」被包裹起來的控制,這似乎是裏面,我不認爲這是可怕的。每個橢圓都有明確的定義,並具有不同的觸發器,每個觸發器都指示自己的狀態。你已經將基本風格的因素考慮在內,這很好。

您可以將單獨的橢圓包裝在具有ActiveState屬性和ActiveFill屬性的另一個用戶控件(不需要備用ViewModel)中。那麼你的交通燈看起來像:

<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> 

這讓你包裹你的指標控制和控制需要擔心的是比較StateActiveState以確定它是否應該填寫的唯一的事情裏面所有的橢圓造型本身用ActiveFill刷。

至於這是否值得付出努力,取決於你有多少這些東西在你周圍漂浮,如果你在你的Traffic Light用戶控制之外使用它們。記住:你不會需要它。

+0

我想過創建一個單獨的控件,但希望可能有其他方式來消除重複。感謝你的回答! – 2010-03-17 16:26:47