Reputation: 270
I am new to WPF and here is what I am trying to do. I want to change a button's style, which is a static resource, based on whether a radio button is checked on not. Below is sample code:
<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>
So when 'Yes' is checked, I want to change the 'Proceed' button style to BlueButton (another static resource) and when 'No' is checked, I want to change the 'Stop' button style to BlueButton. Of course this is part of a bigger problem so I just trying to be specific with the sample example.
The part I am stuck at is how to update the StaticResource from WhiteButton to BlueButton based on the radio button checked status. Any direction would be greatly appreciated.
Thanks.
Upvotes: 1
Views: 5273
Reputation: 6680
Check out http://Globalizer.codeplex.com.
It switches out the entire style when it switches a language.
You basically look up the style in the resource dictionary, kill it and load a new one.
Upvotes: 0
Reputation: 69959
You don't need to change the whole Style
to do that. You can just add a simple DataTrigger
to react directly to the Checkbox.IsChecked
property. It's far simpler to declare the Style
s like this instead:
<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>
Even if you want more properties to change, you can just declare the default ones as plain Setter
s and the ones triggered by the Checkbox.IsChecked
property inside the DataTrigger
. If you have lots of common properties in the two Style
s, then you can still declare them all in one and base the other one on that one and just add the different DataTrigger
.
Upvotes: 5
Reputation: 947
We can replace the entire style using IMultiValue Converter.
For your requirement I came up with this example
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>
I have used this good article http://social.msdn.microsoft.com/Forums/vstudio/en-US/b25973bb-9e9c-4a99-8234-39a042e0a478/apply-styles-dynamically-to-buttons-in-xaml?forum=wpf earlier to tackle my issue.
Upvotes: 2
Reputation: 8111
I'm not sure if you can replace the complete Style but you can user a DataTrigger to change some properties of the button:
<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>
Upvotes: 1