I try to built a DataGrid, and I want to bind one of the TextColums' Foreground property to a Date, so that it becomes red, if the Date is in the past.
Here the XAML:
<toolkit:DataGridTextColumn
Binding="{Binding Path=Prüfdatum, Converter={StaticResource TimestampToDateConverter}}"
Header="Prüfdatum"
Foreground="{Binding Path=Prüfdatum, Converter={StaticResource TimestampToColorConverter},
ConverterParameter=Prüfdatum}" />
Here my Converter:
class TimestampToColorConverter: IValueConverter
{
#region IValueConverter Member
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
string Datum = value.ToString();
int year = System.Convert.ToInt32(Datum.Substring(6, 4));
int month = System.Convert.ToInt32(Datum.Substring(3, 2));
int day = System.Convert.ToInt32(Datum.Substring(0, 2));
int hour = System.Convert.ToInt32(Datum.Substring(11, 2));
int minute = System.Convert.ToInt32(Datum.Substring(14, 2));
int second = System.Convert.ToInt32(Datum.Substring(17, 2));
DateTime Time = new DateTime(year, month, day, hour, minute, second);
if (Time < System.DateTime.Now)
{
return Brushes.Red as Brush;
}
else
{
return Brushes.Black as Brush;
}
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
#endregion
}
I don't know what is wrong, but the Converter is not even caled (The first Converter works perfectly). The output window shows this:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Prüfdatum; DataItem=null; target element is
'DataGridTextColumn' (HashCode=16187528); target property is 'Foreground' (type 'Brush')
I hope you can help me, guys
Thx
DataGridTextColumn tells the DataGrid to create a TextBlock for every row in that column. DataGridTextColumn.Binding then setups a binding for TextBlock.Text, which gets fired each time a new row and a new TextBlock for that row gets created.
I don't know if the binding ever gets executed, but at most once (i.e. not for every row):
Binding="{Binding Path=Prüfdatum, Converter={StaticResource TimestampToDateConverter}}"
The correct solution is to create a style for that textblock and to define a binding for ForeGround. This will get executed for every TextBlock generated. The challenge here is for the TextBlock to find the data. This can be achieved with a relative binding to DataGridRow, an ancestor in the visual tree. DataGridRow.Item gives access to the data behind the grid:
<Window.Resources>
<Style x:Key="ForegroundStyle" TargetType="TextBlock">
<Setter Property="Foreground"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}},
Path=Item.Prüfdatum,
Converter={StaticResource TimestampToColorConverter}/>
</Style>
</Window.Resources>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding SomeData}" ElementStyle="{StaticResource ForegroundStyle}"/>
</DataGrid.Columns>
Complicated right ? I recommend you to read my detailed article about datagrid formatting at: http://www.codeproject.com/Articles/683429/Guide-to-WPF-DataGrid-formatting-using-bindings?msg=5037235#xx5037235xx
Good luck, you need it :-)
The DataGridTextColumn Foreground property data binding does not work.
Peter Huber's answer is a good solution. Here is a slightly simpler alternative.
<DataGridTemplateColumn Header="Heading">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<TextBlock Text="{Binding SomeData}"
Foreground="{Binding SomeData, Converter={StaticResource TimestampToColorConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With