2014-03-06 164 views
0

我是WPF的新手,這是我正在嘗試做的。我想根據是否選中單選按鈕來更改按鈕的樣式,這是一種靜態資源。下面是示例代碼:WPF MVVM動態地改變靜態資源樣式

<RadioButton Name="rbInfoCorrect" 
      GroupName="InfoQuestion" 
      cal:Message.Attach="ShouldProceed"> 
     <RadioButton.Content> 
     <TextBlock Text="Yes" Foreground="White"/> 
     </RadioButton.Content> 
</RadioButton> 
<RadioButton Name="rbInfoNotCorrect" 
      GroupName="InfoQuestion" 
      cal:Message.Attach="ShouldStop"> 
     <RadioButton.Content> 
     <TextBlock Text="No" Foreground="White"/> 
     </RadioButton.Content> 
</RadioButton> 


<Button x:Name="btnProceed" cal:Message.Attach="Proceed"> 
    <Button.Style> 
    <Style TargetType="Button" BasedOn="{StaticResource WhiteButton}"/> 
    </Button.Style> 
</Button> 
<Button x:Name="btnStop" cal:Message.Attach="Stop"> 
    <Button.Style> 
    <Style TargetType="Button" BasedOn="{StaticResource WhiteButton}"/> 
    </Button.Style> 
</Button> 

所以,當「是」被選中,我想將「繼續」按鈕改變風格BlueButton(其他靜態資源),當「否」被選中,我想改變「停止」按鈕樣式到BlueButton。當然,這是一個更大的問題的一部分,所以我只是試圖具體說明示例。

我被卡住的部分是如何基於單選按鈕檢查狀態更新從WhiteButton到BlueButton的StaticResource。任何方向將不勝感激。

謝謝。

回答

2

我們可以通過IMultiValue轉換器更換整個風格。

對於您的要求,我想出了這個例子

public class StyleConverter : IMultiValueConverter 
    { 
     public object Convert(object[] values, Type targetType, 
     object parameter, CultureInfo culture) 
     { 
      if (values.Length < 1) 
       return Binding.DoNothing; 
      bool isCorrect = (bool)values[0]; 
      bool isNotCorrect = (bool)values[1]; 
      Style firstStyle = (Style)values[2]; 
      Style secondStyle = (Style)values[3]; 
      if (isCorrect) 
       return firstStyle; 
      if (isNotCorrect) 
       return secondStyle; 
      return Binding.DoNothing; 

     } 

     public object[] ConvertBack(object value, Type[] targetTypes, 
      object parameter, CultureInfo culture) 
     { 
      throw new NotSupportedException(); 
     } 
    } 

XAML

<Window x:Class="StackWpf.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:StackWpf" 
     Title="MainWindow" Name="window" Height="350" Width="525" > 
    <Window.Resources> 

     <ResourceDictionary> 
      <Style TargetType="Button" x:Key="WhiteStyle"> 
       <Setter Property="Background" Value="White"/> 
      </Style> 
      <Style TargetType="Button" x:Key="BlueStyle"> 
       <Setter Property="Background" Value="Blue"/> 
      </Style> 
      <local:StyleConverter x:Key="styleConverter"/> 
     </ResourceDictionary> 
    </Window.Resources> 

    <Grid> 
     <RadioButton Name="rbInfoCorrect" IsChecked="False" 
      GroupName="InfoQuestion" Margin="80,19,382,257"> 
      <RadioButton.Content> 
       <TextBlock Text="Yes" Foreground="Black"/> 
      </RadioButton.Content> 
     </RadioButton> 
     <RadioButton Name="rbInfoNotCorrect" IsChecked="False" 
      GroupName="InfoQuestion" Margin="80,38,391,257"> 
      <RadioButton.Content> 
       <TextBlock Text="No" Foreground="Black"/> 
      </RadioButton.Content> 
     </RadioButton> 
     <Button Content="Button" Margin="80,114,294,161"> 
      <Button.Style> 


         <MultiBinding Converter="{StaticResource styleConverter}"> 
          <Binding ElementName="rbInfoCorrect" 
          Path="IsChecked" /> 
          <Binding ElementName="rbInfoNotCorrect" 
          Path="IsChecked" /> 
          <Binding Source="{StaticResource WhiteStyle}" /> 
          <Binding Source="{StaticResource BlueStyle}" /> 
         </MultiBinding> 


      </Button.Style> 
     </Button> 

    </Grid> 
</Window> 

我已經使用這個好文章http://social.msdn.microsoft.com/Forums/vstudio/en-US/b25973bb-9e9c-4a99-8234-39a042e0a478/apply-styles-dynamically-to-buttons-in-xaml?forum=wpf早些時候,以解決我的問題。

1

我不知道你是否能代替完整的風格,但你可以用戶DataTrigger改變按鈕的一些屬性:

<Button.Style> 
     <Style TargetType="Button" BasedOn="{StaticResource WhiteButton}"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ElementName=rbInfoCorrect, Path=IsChecked}" Value="True"> 
      <Setter Property="Background" Value="White" /> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding ElementName=rbInfoCorrect, Path=IsChecked}" Value="False"> 
      <Setter Property="Background" Value="Blue" /> 
      </DataTrigger> 
     </Style.Triggers> 
     </Style> 
    </Button.Style> 
+0

感謝您的回覆,但我正在尋找一種方式來改變不僅僅是像漸變和其他東西的背景屬性,所以我想要一種方式來重用現有的樣式資源。 – Harish

1

你不需要改變整個Style來做到這一點。您只需添加一個簡單的DataTrigger即可對Checkbox.IsChecked屬性直接作出反應。這是簡單得多申報Style就像這個:

<Style x:Key="ProceedButtonStyle" TargetType="{x:Type Button}"> 
    <Setter Property="Background" Value="White" /> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding IsChecked, ElementName=rbInfoCorrect}" 
      Value="True"> 
      <Setter Property="Background" Value="Blue" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

<Style x:Key="StopButtonStyle" TargetType="{x:Type Button}"> 
    <Setter Property="Background" Value="White" /> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding IsChecked, ElementName=rbInfoNotCorrect}" 
      Value="True"> 
      <Setter Property="Background" Value="Blue" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

即使你想更多的屬性改變,你可以聲明裏面的DataTrigger默認的值,爲純Setter S和那些由Checkbox.IsChecked屬性觸發。如果在兩個Style中有很多共同屬性,那麼您仍然可以將它們全部歸併爲一個,並將另一個基於另一個並僅添加不同的DataTrigger

+0

感謝您的回覆,但我期待替換整個樣式,因爲我在觸發器中設置的屬性數量不止。所以,我試圖以某種方式重用現有的樣式資源,而不是設置屬性。 – Harish