Reputation: 830
What is the best (easy) way to set the font to a strikethrough style on individual cells of the WPF DataGrid?
...
Options that I'm aware of are inserting TextBlock controls in individual cells or using a DataGridTemplateColumn - and using the TextDecorations property therein. Either way this is quite a mission, I'd like to use the default AutoGenerate Columns function of DataGrid, especially since my ItemsSource is a DataTable.
As and aside, is there any way to access the TextBlock generated using the default DataGridTextColumn?
Upvotes: 6
Views: 7324
Reputation: 3312
If you want to bind the strikethrough based on a particular cell, you have a binding problem, because the DataGridTextColumn.Binding changes only the content of TextBox.Text. If the value of the Text property is all you need you can bind to the TextBox itself:
<Setter Property="TextDecorations"
Value="{Binding RelativeSource={RelativeSource Self},
Path=Text,
Converter={StaticResource TextToTextDecorationsConverter}}" />
But if you want to bind to something different than TextBox.Text, you have to bind through the DataGridRow, which is a parent of the TextBox in the visual tree. The DataGridRow has an Item property, which gives access to the complete object used for the whole row.
<Setter Property="TextDecorations"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}},
Path =Item.SomeProperty,
Converter={StaticResource SomePropertyToTextDecorationsConverter}}" />
The converter looks like this, assuming the something is of type boolean:
public class SomePropertyToTextDecorationsConverter: IValueConverter {
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
if (value is bool) {
if ((bool)value) {
TextDecorationCollection redStrikthroughTextDecoration =
TextDecorations.Strikethrough.CloneCurrentValue();
redStrikthroughTextDecoration[0].Pen =
new Pen {Brush=Brushes.Red, Thickness = 3 };
return redStrikthroughTextDecoration;
}
}
return new TextDecorationCollection();
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}
Upvotes: 0
Reputation: 184647
<DataGridTextColumn Binding="{Binding Name}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextDecorations" Value="Strikethrough"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
Of course you can wrap the setter in a DataTrigger to use it selectively.
Upvotes: 6