WPF change Fill Color Brush - wpf

In a Resource Dictionary I have stored a ViewBox with a Canvas
<Style x:Key="MyPathStyle" TargetType="Path">
<Setter Property="Fill" Value="{Binding BackgroundColorBrush,
RelativeSource={RelativeSource AncestorType=iconcontrols:IconAsVisualBrush}}"/>
</Style>
<Viewbox x:Key="Icon2">
<Canvas Width="40.000" Height="40.000">
<Canvas>
<Path Fill="#ff99baf4" Data="F1 M 14.377,23.798" />
<Path Style="{StaticResource MyPathStyle}" Data="..." />
</Canvas>
</Canvas>
</Viewbox>
So I want to change the color of the second Path using the BackgroundColorBrush of my control Container (called IconAsVisualBrush ).
It is
<Grid x:Name="GridIconBrush" Width="40" Height="40">
<Grid.Background>
<VisualBrush x:Name="CtrlVisualBrush" Stretch="Uniform" />
</Grid.Background>
</Grid>
The VisualBrush is set in cs:
private static void OnIconBrushResourceChanged(DependencyObject source
, DependencyPropertyChangedEventArgs e)
{
IconAsVisualBrush control = source as IconAsVisualBrush;
control.CtrlVisualBrush.Visual = (Viewbox)Application.Current.FindResource(e.NewValue);
}
In my UserControl I can draw the ViewBox with the folliwing xaml:
<iconcontrols:IconAsVisualBrush BackgroundColorBrush="White"
IconBrushResource="Icon2"/>
<iconcontrols:IconAsVisualBrush BackgroundColorBrush="Red"
IconBrushResource="Icon2"/>
The canvas is correctly drawn but not the color. I receive:
Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='IconAsVisualBrush', AncestorLevel='1''. BindingExpression:Path=BackgroundColorBrush; DataItem=null; target element is 'Path' (Name=''); target property is 'Fill' (type 'Brush')
Is there a way to change only the Path Fill color set inside a owner Control (not a dynamic resource that make all IconAsVisualBrush with the same color) so that I can draw the same shape with different fill colors?

Your issue is that the Setter in your Style is unable to find the IconAsVisualBrush, presumably because it is not part of the Path's visual tree. Have you considered using triggers? It's difficult to suggest a solution without knowing your application architecture and what is calling OnIconBrushResourceChanged - however since we're talking about WPF, I'll make an educated guess that you are using MVVM. If so, you could use DataTriggers like so:
<Style x:Key="MyPathStyle" TargetType="Path">
<Setter Property="Fill" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{MyColourChangedProperty}"
Value="True">
<DataTrigger.Setters>
<Setter Property="Fill" Value="Red"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
EDIT: To clarify, the style I've suggested here will give you a default fill of white, but if you set 'MyColourChangedProperty' (or whatever you bind to) to true, it will turn red.

Related

Override property of custom style

I have Style that applies to all of the buttons of my application:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="StatusButtonCircle" Stroke="Black" StrokeThickness="0" Fill="AliceBlue" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircle" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<Ellipse x:Name="StatusButtonCircleHighlight" Margin="4" Stroke="Black" StrokeThickness="2" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircleHighlight" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
... some Triggers here
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I change properties (e.g. FontWeight, FontSize etc.) in XAML? I tried this:
<Button FontWeight="Bold" FontSize="30" Foreground="Red">
</Button>
In the designer-view, I see the changes. But during runtime those changes are not applied.
After some investigation, I also have a Style for all TextBlock like this:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Segoe UI Semibold" />
<Setter Property="Foreground" Value="White" />
</Style>
This Style seems to override the TextBlock that is used on the Button. I still can't change the Text Properties in XAML.
Here's what it looks like if I use the Styles above in an empty project:
In the designer, the changes are applied, during runtime the one from the TextBlock are applied. If I assign a x:Key to the TextBlock, it works fine. But then I have to assign this Style to every TextBlock used in the app manually.
You are facing typical style inheritance issue in wpf.
A control looks for its style at the point when it is being initalized. The way the controls look for their style is by moving upwards in logical tree and asking the logical parent if there is appropriate style for them stored in parent's resources dictionary.
In your case, you are using ContentPresenter in button as a default behaviour. and it is using TextBlock to represent text in button by default.
Therefore at the time of initialization, ContentPresenter finding TextBlock style and applying to represent content in button.
If you want to restrict ContentPresenter to look for the style then you have to bind a blank style to content presenter so that it will not look for any further style.
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="StatusButtonCircle" Stroke="Black" StrokeThickness="0" Fill="AliceBlue" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircle" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<Ellipse x:Name="StatusButtonCircleHighlight" Margin="4" Stroke="Black" StrokeThickness="2" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircleHighlight" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock" BasedOn="{x:Null}"/>
<!-- Assigned Blank style here therefore it will not search for any further style-->
</ContentPresenter.Resources>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You can do it with the BasedOn. I show you an example.
<Window.Resources>
<Style TargetType="ToggleButton" BasedOn="{StaticResource DefToggleButton}">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Content" Value="Some Cool Stuff"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="More Stuff"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Here in my resources I have DefToggleButton, now in my xaml file I can set up any Property according to my need (which in this case is the FontWeight and Content Property).
I think if you remove the Template from your Style, then you can do what you want to do, like this:
<Window.Resources>
<Style TargetType="Button" x:Key="stBtn>
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Segoe UI Semibold" />
</Style>
</Window.Resources>
The Template that you have says, that all Buttons should be shown as a Border with a ContentPresenter inside, which is not what you have asked.
Without the Template, you can define your Buttons like this:
<Button Content="Hi!" Style="{StaticResource stBtn}" Foreground="Red" >
Like this, you have a Blue Button with Red Foreground.
=================
Edit
So what if you define a Template, and use it in you style, like this?
Then, by TemplateBinding you can define that the Foreground and teh Content come later, when the Button is actually defined.
<Window.Resources>
<ControlTemplate x:Key="ctBtn" TargetType="{x:Type Button}">
<Label Background="Green" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}"/>
</ControlTemplate>
<Style x:Key="stBtn2" TargetType="{x:Type Button}">
<Setter Property="Template"
Value="{StaticResource ctBtn}" />
</Style>
<Window.Resources>
Then by defining the Button:
<Button Content="Hi!" Style="{StaticResource stBtn2}" Foreground="Red" >
===============
Edit2
So the general idea is that you can define a TemplateBinding for the properties of the elements in your template. So for example,you have an Ellipse in your template:
<Ellipse Fill="{TemplateBinding BorderBrush}" />
This defines that the Fill property of your Ellipse comes from the BorderBrush of your Button (Assuming that the template is targeting a Button)
Accordingly, you can put a Label in your Template, and set a TemplateBinding for its Forground and FontWeight property.
<Label Foreground="{TemplateBinding Foreground}" />
First, for this issue to be reproduced, Styles need to be set within a ResourceDictionary which is then added to Application.Resources (precisellyTextBlock global style). Setting Styles within for example Window.Resources will not reproduce the issue.
Global TextBlock Style is applied to the TextBlock created by ConentPresenter
As noticed in the question, the issue is that the global (keyless) Style for TextBlock is applied to the TextBlock created by ContentPresenter when it concludes the content to display is a string. For some reason this doesn't happen when that Style is defined within Window.Resources. As it turns out, there is more to this than just "controls are looking for their styles within their parent's resources".
ControlTemplate is a boundary for elements not deriving from Control class
For TextBlock (which doesn't derive from Control class, but from UIElement) within ControlTemplate, it means that wpf will not look for it's implicit Style beyond it's templated parent. So it won't look for implicit Style within it's parent's resources, it will apply application level implicit Style found within Application.Resources.
This is by design (hardcoded into FrameworkElement if you will), and the reason is exactly to prevent issues like this one. Let's say you're creating a specific Button design (as you are) and you want all buttons in your application to use that design, even buttons within other ControlTemplates. Well, they can, as Button does derive from Control. On the other hand, you don't want all controls that use TextBlock to render text, to apply the implicit TextBlock Style. You will hit the same issue with ComboBox, Label... as they all use TextBlock, not just Button.
So the conclusion is: do not define global Style for elements which don't derive from Control class within Application.Resources, unless you are 100% sure that is what you want (move it to Window.Resources for example). Or, to quote a comment I found in source code for MahApps.Metro UI library: "never ever make a default Style for TextBlock in App.xaml!!!". You could use some solution to style the TextBlock within your Button's ControlTemplate, but then you'll have to do it for Label, ComboBox, etc... So, just don't.

How to change the foreground color of all command buttons in MahApps

Is there a way to change buttons foreground in MetroWindow?
I have even tried to override the IronicallyNamedChromelessButtonStyle but the foreground color was still the same.
Edit:
The buttons are in the Window Bar (e.g Close, Minimize, Maximize).
After a deep dive into the MahApps codе... Here is the source which is responsible for the buttons:
https://github.com/MahApps/MahApps.Metro/blob/master/MahApps.Metro/Themes/MetroWindow.xaml
If you look carefully, you will notice that every style has triggers that override the style foreground with hard-coded "White":
<Style.Triggers>
<DataTrigger Binding="{Binding ShowTitleBar, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:MetroWindow}}}"
Value="True">
<Setter Property="Foreground"
Value="White" />
</DataTrigger>
<DataTrigger Binding="{Binding ShowTitleBar, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:MetroWindow}}}"
Value="False">
<Setter Property="Background"
Value="Transparent" />
</DataTrigger>
</Style.Triggers>
My solution was to override all necessary style triggers:
<Style TargetType="{x:Type MahControls:WindowButtonCommands}">
<Style.Triggers>
<DataTrigger Binding="{Binding ShowTitleBar, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MahControls:MetroWindow}}}"
Value="True">
<Setter Property="Foreground"
Value="{StaticResource IdealForegroundColorBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
Hope this will help anyone in my case.
Special thanks to #Rui and #Sankarann for the ideas and help.
If anyone have a better solution, please share it.
You can use an implicit style. An implicit style is a style that does not have a "key", for example, if you add this style in Application.Resources it will affect all buttons in your application:
<Application.Resources>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Blue"/>
</Style>
</Application.Resources>
You can set it in, for example, a Grid's Resources and it will affect only the Buttons inside that Grid.
Yes your right the colours are applied in appbar_ canvas via
Fill="{DynamicResource BlackBrush}"
So as your not in control of BlackBrush you cant really apply a SolidColorBrush to it as some other control in the MahApps Library will overwite your setting.
You need to point NuGet to the Loose resources file (so you get an Icons.xaml file to play with locally)
Copy the appbar icons you want to change color (maybe create a resource dictionary called MyIcons.xaml and save them in there, adding MyIcons.xaml to your App.xaml MergedDictionaries)
Then in MyIcons.xaml define your icon (with its new colour too) :
<SolidColorBrush x:Key="IconBrushOrange" Color="Orange" />
<Canvas x:Key="my_connecting" All other fields...>
<Path Stretch="Fill" Fill="{StaticResource IconBrushOrange}" All other fields.... />
</Canvas>
Then in your UI :
<Rectangle Width="20" Height="20">
<Rectangle.Fill>
<VisualBrush Stretch="Fill" Visual="{StaticResource my_connecting}" />
</Rectangle.Fill>
</Rectangle>
Just redefine the Brush in window resources:
<SolidColorBrush x:Key="MahApps.Brushes.IdealForeground" Color="WhateverColor" />

WPF Validation.ErrorTemplate Background Object

I want to replace the normal behaviour of Validation.ErrorTemplate.
I want to put a background border object (filled with red color) behind my own UserControl
and then apply a simple color animation to blink it.
I tried this in my implicit control style:
<Style TargetType="{x:Type local:myControl}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Border Name="ErrorBorder" CornerRadius"5" Background="Red">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding
RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
</Style>
Unfortunately the border object entirely overlays the control UI.
The other question is: where is the right place to put a DoubleAnimation applied on Opacity to make my Background blinking? Wich property/event should I trigger? Should I use style or simply place it in the Border.Triggers?
Thank you
I'm pretty sure this isn't possible, adorners are always drawn on top of the adorned element.
See the Adorners Overview on MSDN
"An Adorner is a custom FrameworkElement that is bound to a UIElement. Adorners are rendered in an AdornerLayer, which is a rendering surface that is always on top of the adorned element or a collection of adorned elements"
You could probably get the same effect by adorning with a normal border that just borders the adorned element instead of trying to stick it behind the adorned element.

Why does data binding my chart series color fail?

I am drawing simple line charts using the WPF toolkit. My goal is to set the line color of my series via Data Binding. This succeeds only partially. The question is: why?
Setup
Namespaces:
xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit" x:Class="WpfApplication3.MainWindow"
xmlns:media="clr-namespace:System.Windows.Media;assembly=PresentationCore"
Chart:
<chartingToolkit:Chart x:Name="chart">
<chartingToolkit:LineSeries x:Name="seriesEntries" IndependentValueBinding="{Binding Key}" DependentValueBinding="{Binding Value}" DataPointStyle="{StaticResource CommonLineSeriesDataPoint}">
<chartingToolkit:LineSeries.Tag>
<media:Brush>Green</media:Brush>
</chartingToolkit:LineSeries.Tag>
</chartingToolkit:LineSeries>
</chartingToolkit:Chart>
Ignore the Tag for now, it will be relevant later.
Notice the chart has a custom data point style, CommonLineSeriesDataPoint:
<Style x:Key="CommonLineSeriesDataPoint" TargetType="chartingToolkit:LineDataPoint">
<Setter Property="Background">
<Setter.Value>
<media:Brush>Red</media:Brush>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="chartingToolkit:LineSeries">
<Setter Property="DataPointStyle" Value="{StaticResource CommonLineSeriesDataPoint}" />
</Style>
As expected, this colors my line series red:
Breaking Change
Now I want to data bind my data point background. I make only one change. Instead of specifying the background brush directly, I bind it to the Tag property of my LineSeries, which is also a brush (see previous LineSeries declaration, it's a green one).
<Style x:Key="CommonLineSeriesDataPoint" TargetType="chartingToolkit:LineDataPoint">
<Setter Property="Background">
<Setter.Value>
<Binding Path="Tag" RelativeSource="{RelativeSource AncestorType={x:Type chartingToolkit:LineSeries}}" />
</Setter.Value>
</Setter>
</Style>
<Style TargetType="chartingToolkit:LineSeries">
<Setter Property="DataPointStyle" Value="{StaticResource CommonLineSeriesDataPoint}" />
</Style>
The result is this:
So the dots are green. But the line is gone.
My expectation is to see a green line as well! Where is it?
I found a solution after digging in the WPF Toolkit Sources.
Turns out the Stroke property of the series' Polyline is bound to a Background property via TemplateBinding. I suspect this doesn't go well with my try binding the Background property itself.
This answer on SO suggests that TemplateBinding is evaluated at compile time. So let's get rid of the TemplateBinding and bind the Stroke property directly to the Tag of my LineSeries (remember: the Tag contains the green brush).
From the WPF Toolkit Source \Source\DataVisualization\Themes\generic.xaml I copied part of the style definition for the LineSeries and added it to my ResourceDictionary:
<Style x:Key="CommonLineSeries" TargetType="chartingToolkit:LineSeries" BasedOn="{StaticResource {x:Type chartingToolkit:LineSeries}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="chartingToolkit:LineSeries">
<Canvas x:Name="PlotArea">
<Polyline Points="{TemplateBinding Points}" Stroke="{Binding Tag, RelativeSource={RelativeSource AncestorType={x:Type chartingToolkit:LineSeries}}}" Style="{TemplateBinding PolylineStyle}"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
(If interested you can search for <!-- charting:LineSeries --> in generic.xaml to find the source I copied from.)
The only thing I modified is the binding of Stroke. Here I use the same binding I used for my data points.
Last thing to do: tell the LineSeries to use this style:
<chartingToolkit:LineSeries x:Name="seriesEntries" IndependentValueBinding="{Binding Key}" DependentValueBinding="{Binding Value}" DataPointStyle="{StaticResource CommonLineSeriesDataPoint}" Style="{StaticResource CommonLineSeries}">
And lo and behold, it works. The line is back and it's green:
(If you look closely you see that the legend entry for the series still has the wrong color. But I assume the solution will be quite similar to the above.)

Creating a WPF ValueConverter for a Brush

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?
For this kind of UI state updates, try using triggers instead; it'll save you from writing a value converter, and it's a lot shorter to write.
Try this:
<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>
<!-- Base Arrow Style, with a trigger to toggle it Gray when its parent button is disabled -->
<Style x:Key="ArrowStyle" TargetType="Path">
<Setter Property="Width" Value="10"/>
<Setter Property="Height" Value="8"/>
<Setter Property="Stretch" Value="Fill"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled}" Value="False">
<Setter Property="Fill" Value="Gray"/>
</DataTrigger>
</Style.Triggers>
</Style>
<!-- Left Arrow Style, with the Left Arrow fill and data -->
<Style x:Key="LeftArrowStyle" BasedOn="{StaticResource ArrowStyle}" TargetType="Path">
<Setter Property="Fill" Value="Black"/>
<Setter Property="Data" Value="{StaticResource LeftArrow}"/>
</Style>
<!-- Right Arrow Style, with the Right Arrow fill and data -->
<Style x:Key="RightArrowStyle" BasedOn="{StaticResource ArrowStyle}" TargetType="Path">
<Setter Property="Fill" Value="Red"/>
<Setter Property="Data" Value="{StaticResource RightArrow}"/>
</Style>
</Application.Resources>
<Button x:Name="BackButton" Padding="5,5,5,5" IsEnabled="False">
<Path Style="{StaticResource LeftArrowStyle}"/>
</Button>
<Button x:Name="ForwardButton" Padding="5,5,5,5">
<Path Style="{StaticResource RightArrowStyle}"/>
</Button>
</Application>
Then, you set your default fill in LeftArrowStyle and RightArrowStyle, for the left and right arrows, respectively. If you set it on the Path itself, then that value would take precedence and override anything a style or its trigger may do. The base style, ArrowStyle, contains a DataTrigger bound to the parent button - it fires whenever IsEnabled is false, and changes the Path's Fill to Gray.
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>
Your code essentially works. I think your static resource may be wrong as your not specifying where this is getting the converter from.
You probably need
<Window.Resources>
<conv:EnabledColorConverter x:Key="brushConv" />
</Window.Resources>
and then specify your binding as:
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=IsEnabled, Converter={StaticResource brushConv}}

Resources