On the Nerd Plus Art blog today, there was a post about creating WPF Resources for arrows, which the author uses frequently. I have a side project that has Back and Forward buttons, so I thought that the Left and Right arrows would work great on those buttons.
I added the LeftArrow
and RightArrow
Geometries to my application's resources, and then used them as the content of the buttons:
<Application x:Class="Notes.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<Geometry x:Key="RightArrow">M0,0 L1,0.5 0,1Z</Geometry>
<Geometry x:Key="LeftArrow">M0,0.5 L1,1 1,0Z</Geometry>
</Application.Resources>
</Application>
<Button x:Name="BackButton"
Padding="5,5,5,5"
Command="{x:Static n:Commands.GoBackCommand}">
<Path Data="{StaticResource LeftArrow}" Width="10" Height="8"
Stretch="Fill" Fill="Black"/>
</Button>
<Button x:Name="ForwardButton"
Padding="5,5,5,5"
Command="{x:Static n:Commands.GoForwardCommand}">
<Path Data="{StaticResource RightArrow}" Width="10" Height="8"
Stretch="Fill" Fill="Red" />
</Button>
That worked, except that the arrows were drawn in black regardless of whether the button was enabled or not. So, I created a ValueConverter
to go from a bool
to a Brush
:
class EnabledColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
bool b = (bool)value;
return b ? Brushes.Black : Brushes.Gray;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}
(I realize that I should probably use system colors instead of hard coded black and gray, but I just wanted to get this working, first.)
I modified the Fill
property of the Path
to use my converter (which I created within the application's resources):
<Path Data="{StaticResource LeftArrow}" Width="10" Height="8"
Stretch="Fill"
Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled, Converter={StaticResource EnabledColorConverter}}"/>
Unfortunately, this doesn't work, and I'm not sure why. When I run it, the arrow isn't drawn at all. I checked the Output window in Visual Studio, and no binding errors were displayed. I also verified that the bool
is the right value in the converter, based on the whether the button should be enabled or not.
If I change the Path
back to a TextBlock
(and bind its Foreground
property in the same manner as Path.Fill
), the text is always drawn in black.
Am I doing something wrong? Why is the Brush
returned by my converter not used to render the Path
in the button?
Why no just bind the Fill of your Path to the Foreground of the Button?
<Button x:Name="BackButton"
Padding="5,5,5,5"
Command="{x:Static n:Commands.GoBackCommand}">
<Path Data="{StaticResource LeftArrow}" Width="10" Height="8"
Stretch="Fill" Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=Foreground"/>
</Button>