Reputation: 10738
EDIT:
Maybe I'm over complicating things by trying to swap styles since really the only thing I want is to be able to use different background images based on the status of the boolean property. The question should be more... How can I use a background image to a button based on the status of the boolean property?
I have two styles that animate and swap images when a mouse is over on a button, the styles work fine but what I want is to be able to use one of the styles based on the status of a Boolean property. Something like... If property equals true, use style1 otherwise use style2
.
Here is my code:
<Storyboard x:Key="MouseOverStoryboard" Duration="00:00:00.5">
<DoubleAnimation Storyboard.TargetName="image1" Storyboard.TargetProperty="Opacity" To="0" Duration="00:00:00.3" />
<DoubleAnimation Storyboard.TargetName="image2" Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:00.3" />
</Storyboard>
<Storyboard x:Key="MouseLeaveStoryboard" Duration="00:00:00.5">
<DoubleAnimation Storyboard.TargetName="image1" Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:00.3" />
<DoubleAnimation Storyboard.TargetName="image2" Storyboard.TargetProperty="Opacity" To="0" Duration="00:00:00.3" />
</Storyboard>
<Style x:Key="Style1"
TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="image1" Source="Images/image.png" Stretch="None" />
<Image x:Name="image2" Source="Images/image-hover.png" Stretch="None" Opacity="0" />
<ContentPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
<BeginStoryboard Name="MouseOverStoryboard"
Storyboard="{StaticResource MouseOverStoryboard}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
<BeginStoryboard Name="MouseLeaveStoryboard"
Storyboard="{StaticResource MouseLeaveStoryboard}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Style x:Key="Style2"
TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="image1" Source="Images/image2.png" Stretch="None" />
<Image x:Name="image2" Source="Images/image-hover2.png" Stretch="None" Opacity="0" />
<ContentPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
<BeginStoryboard Name="MouseOverStoryboard"
Storyboard="{StaticResource MouseOverStoryboard}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
<BeginStoryboard Name="MouseLeaveStoryboard"
Storyboard="{StaticResource MouseLeaveStoryboard}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Button x:Name="MyButton"
Command="{Binding ButtonCommand}">
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers>
<DataTrigger Binding="{Binding SomeBooleanProperty}" Value="True">
<Setter Property="Style" Value="{StaticResource Style1}" />
</DataTrigger>
<DataTrigger Binding="{Binding SomeBooleanProperty}" Value="True">
<Setter Property="Style" Value="{StaticResource Style2}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Style object is not allowed to affect the Style property of the object to which it applies.
What I'm I missing?
Upvotes: 1
Views: 887
Reputation: 10738
Here is what I ended up doing that worked with a single style.
<Style x:Key="Style1" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding SomeBooleanProperty}" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="image1" Source="Images/image.png" Stretch="None" />
<Image x:Name="image2" Source="Images/image-hover.png" Stretch="None" Opacity="0" />
<ContentPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
<BeginStoryboard Name="MouseOverStoryboard" Storyboard="{StaticResource MouseOverStoryboard}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
<BeginStoryboard Name="MouseLeaveStoryboard" Storyboard="{StaticResource MouseLeaveStoryboard}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsCSomeBooleanPropertyurrentPage}" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="image1" Source="Images/image2.png" Stretch="None" />
<Image x:Name="image2" Source="Images/image-hover2.png" Stretch="None" Opacity="0" />
<ContentPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
<BeginStoryboard Name="MouseOverStoryboard" Storyboard="{StaticResource MouseOverStoryboard}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
<BeginStoryboard Name="MouseLeaveStoryboard" Storyboard="{StaticResource MouseLeaveStoryboard}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Upvotes: 0
Reputation: 169200
You can't set the Style
property of en element in a Setter
of a Style
that is applied to the same element. That's basically what the error message tells you.
You could either use a single Style
and use triggers with conditions in the Style
to make it look different depending on the value of the SomeBooleanProperty
property, or you could use a converter:
class StyleConverter : DependencyObject, IValueConverter
{
public Style Style1 { get; set; }
public Style Style2 { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool b = (bool)value;
return b ? Style1 : Style2;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
XAML:
<Button x:Name="MyButton" Content="Button" Command="{Binding ButtonCommand}">
<Button.Style>
<Binding Path="SomeBooleanProperty">
<Binding.Converter>
<local:StyleConverter Style1="{StaticResource Style1}" Style2="{StaticResource Style2}" />
</Binding.Converter>
</Binding>
</Button.Style>
</Button>
Upvotes: 2
Reputation: 1819
I don't believe that's the way to do this. You could set your styles in code behind, but a better way is to get rid of Style2 and combine with Style1 like this:
<Style x:Key="Style1"
TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="image1"
Source="Images/image.png" Stretch="None" />
<Image x:Name="image2"
Source="Images/image-hover.png" Stretch="None"
Opacity="0" />
<ContentPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="image1" Property="Source"
Value="Images/image2.png"/>
<Setter TargetName="image2" Property="Source"
Value="Images/image-hover2.png"/>
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="MouseLeaveStoryboard" />
<BeginStoryboard Name="MouseOverStoryboard"
Storyboard="{StaticResource MouseOverStoryboard}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="MouseOverStoryboard" />
<BeginStoryboard Name="MouseLeaveStoryboard"
Storyboard="{StaticResource MouseLeaveStoryboard}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
And then you can just write:
<Button Style="{StaticResource Style1}"/>
Done.
Upvotes: 2