I have a converter that takes a decimal value and converts it to a brush (red for negative and black for positive input). I also created a style that I want to apply to all DataGridTextColumn that will take decimal values. If I inline the style for each DataGridTextColumn I can simply specify the related property on the Datacontext in the binding expression. However I don’t want to inline the style and simply have it as a resource, that way I can set the CellStyle to the resource. The problem is I don’t know what to put in the Binding of the value for the Foreground property. I want to be able to bind it to value that the cell to which it’s being applied is bound to.
Here is what I have:
<Window.Resources>
<!-- This converter takes a decimal value and returns a brush -->
<conv:NumericValueBrushColorConverter x:Key="NumericValueBrushColorConverter"></conv:NumericValueBrushColorConverter>
<Style x:Key="CurrencyStyle" TargetType="DataGridCell">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Foreground" Value="{Binding WhatGoesHere, Converter={StaticResource NumericValueBrushColorConverter}}"></Setter>
</Style>
</Window.Resources>
<DataGrid ItemsSource="{Binding CashReport}">
<DataGrid.Columns>
<DataGridTextColumn Header="Beginning Cash Available" Binding="{Binding BeginningBalance, StringFormat={}{0:C}}" CellStyle="{StaticResource CurrencyStyle}" />
<DataGridTextColumn Header="Ending Cash Available" Binding="{Binding EndingBalance, StringFormat={}{0:C}}" CellStyle="{StaticResource CurrencyStyle}" />
</DataGrid.Columns>
</DataGrid>
Update #1
As per Jefim’s suggestion I should attempt to use the ElementStyle as it works directly on the rendered TextBlock as opposed to (CellStyle) the content control (whatever that is) that holds the TextBlock.
<Style x:Key="CurrencyStyle" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Foreground" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Text, Converter={StaticResource NumericValueBrushColorConverter}}"/>
</Style>
<DataGrid ItemsSource="{Binding CashReport}">
<DataGrid.Columns>
<DataGridTextColumn Header="Beginning Cash Available" Binding="{Binding BeginningBalance, StringFormat={}{0:C}}" ElementStyle="{StaticResource CurrencyStyle}" />
<DataGridTextColumn Header="Ending Cash Available" Binding="{Binding EndingBalance, StringFormat={}{0:C}}" ElementStyle="{StaticResource CurrencyStyle}" />
</DataGrid.Columns>
</DataGrid>
This seems to work, however when I track my converter’s Convert method it seems to fire about 28 times or so with empty value being passed to the Convert method. After that all values flow as expected. When the grid renders everything looks right, there are no empty cells. What executes my converter the first 20+ times without values?
Update #2
I believe my current issue is unrelated to the original question so I moved it out to: IValueConverter executes more times than expected
You can (and probably should) use the
ElementStyle/EditingElementStyleproperties – they will allow you to style theTextBlockandTextBoxthat are within the cell. E.g.:UPDATE
Updated the code to the same as in the question’s update #1 so that people who look at the answer would see the correct version of code (by e36M3)