Reputation: 187
I'm trying to implement a button that uses XAML-defined icons to show a different state (like in the second comment here: https://codereview.stackexchange.com/questions/183871/wpf-button-with-xaml-defined-icon-that-changes-with-state). The icons are defined with a "Fill" property that uses a RelativeSource binding, like so:
<Canvas x:Key="icon_stop"
x:Shared="False"
Width="76"
Height="76"
Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Rectangle
Width="28.5"
Height="28.5"
Canvas.Left="23.75"
Canvas.Top="23.75"
Stretch="Fill"
Fill="{Binding RelativeSource={
RelativeSource Mode=FindAncestor,
AncestorType=Control
}, Path=Foreground}"
/>
</Canvas>
The button is bound to a property in the window's ViewModel like this:
<Button Name="PlayStopButton"
Padding="20 0 20 0"
Command="{Binding Path=StartStopCommand}">
<ContentControl Style="{StaticResource style_icon}">
<Binding
Path="IsRunning"
UpdateSourceTrigger="PropertyChanged"
FallbackValue="{StaticResource icon_play}">
<Binding.Converter>
<converters:BoolToObjectConverter
TrueObject="{StaticResource icon_stop}"
FalseObject="{StaticResource icon_play}"
NullObject="{StaticResource icon_play}"
/>
</Binding.Converter>
</Binding>
</ContentControl>
</Button>
(I'm omitting the "style" part here and the "BoolToObjectConverter", that should be clear for the purpose)
The problem is that, when I run the program, the button gets correctly updated, but the icon is not visible. This is because the "icon_stop" resource is not updated with the correct "Fill" color. In fact, if I force it (for example to "Black") the icon shows correctly.
It seems to me that the "RelativeSource" bounded property gets not updated. I think this is related to the fact that the resource is a "StaticResource" and thus gets created only once on the application loading.
I've found that there are also "DynamicResource" references in WPF, but I can't use them here (or at least I can't see how now as them must be bound to a dependency property and I have the value converter here).
How can I solve this?
Upvotes: 0
Views: 384
Reputation: 128060
Your XAML seems overly complicated. You may try something simple like this:
<Style TargetType="Button" x:Key="PlayButtonStyle">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Path Fill="{Binding Foreground,
RelativeSource={RelativeSource AncestorType=Button}}"
Data="{Binding}"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Content" Value="M5,0 L25,15 5,30Z"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsRunning}" Value="True">
<Setter Property="Content">
<Setter.Value>
<RectangleGeometry Rect="0,0,30,30"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Try it like this:
<Button Style="{StaticResource PlayButtonStyle}" Foreground="Red" />
Upvotes: 1