WPF MVVM动态更改静态资源样式

时间:2014-03-06 19:35:27

标签: c# wpf

我是WPF的新手,这就是我想做的事情。我想根据是否选中单选按钮来更改按钮的样式,这是一种静态资源。以下是示例代码:

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

所以当选中'Yes'时,我想将'Proceed'按钮样式更改为BlueButton(另一个静态资源),当选中'No'时,我想将'Stop'按钮样式更改为BlueButton。当然这是一个更大问题的一部分,所以我只想尝试具体的示例。

我遇到的部分是如何根据单选按钮检查状态将StaticResource从WhiteButton更新为BlueButton。任何方向将不胜感激。

感谢。

4 个答案:

答案 0 :(得分:3)

您无需更改整个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>

即使您希望更改更多属性,也可以将默认属性声明为普通Setter,以及Checkbox.IsCheckedDataTrigger属性触发的属性。如果你在两个Style中有很多共同的属性,那么你仍然可以将它们全部声明为一个并将另一个属性放在那个属性上,只需添加不同的DataTrigger

答案 1 :(得分:2)

我们可以使用IMultiValue Converter替换整个样式。

根据您的要求,我想出了这个例子

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来解决我的问题。

答案 2 :(得分:1)

我不确定您是否可以替换完整的Style,但您可以使用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>

答案 3 :(得分:0)

查看http://Globalizer.codeplex.com

切换语言时会切换整个样式。

您基本上在资源字典中查找样式,将其删除并加载新样式。