I have a converter that takes the text from a TextBlock that makes up a DataGridCell and converts it to a red or black brush depending if the value is negative or positive. However the converter executes more times than there are items in the datasource of the grid. For example if I simply bind a collection that contains 1 object, the converter executes 2 times. The first time the value
parameter is an empty string, the second time it actually contains the value that I would expect. If I add more objects to the list, the number of initial "empty" executions grows. What am I doing wrong?
<Window.Resources>
<conv:NumericValueBrushColorConverter x:Key="NumericValueBrushColorConverter"></conv:NumericValueBrushColorConverter>
</Window.Resources>
<DataGrid ItemsSource="{Binding CashReport}" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Beginning Cash Available" Binding="{Binding BeginningBalance, StringFormat={}{0:C}}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Foreground" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Text, Converter={StaticResource NumericValueBrushColorConverter}}"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
[ValueConversion(typeof(string), typeof(SolidColorBrush))]
internal class NumericValueBrushColorConverter : IValueConverter
{
static int i = 0;
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string strValue = value as string;
i++;
if(string.IsNullOrEmpty(strValue)) return new SolidColorBrush(Colors.Black);
if (strValue.StartsWith("("))
{
return new SolidColorBrush(Colors.Red);
}
else
{
return new SolidColorBrush(Colors.Black);
}
}
...
}
I expect @Daniel Hilgarth is right. You should check the value in your converter before trying to convert. You can return Binding.DoNothing when you don't want the binding to run.
Well, first the TextBlock in the grid row is created and thus empty (= first execution) and then the content is bound to the value of the current item (= second execution). Nothing wrong here.