I have a DataGrid filled with instances of a class that exposes a double
type property. This property is shown into the DataGrid. I want to implement a custom validation, and I want to color the whole cell red if this validation fails. I think I am close to making it work, but not quite yet, and now I'm stumped.
My problem is that I cannot make the conditional (on validation fail) formatting work. The result is that the cells are correctly colored at the start, but when I insert a value that makes the falidating function return false, I get the usual red border, white background cell style.
How am I supposed to input this formatting style?
XAML code:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<DataGrid x:Name="dg" ItemsSource="{Binding Data}">
<DataGrid.Resources>
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<AdornedElementPlaceholder/>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
</DockPanel>
</ControlTemplate>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}"></Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
</Window>
Code behind:
public partial class MainWindow : Window
{
...
private void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)
{
foreach (DataGridTextColumn c in dg.Columns)
{
c.ElementStyle = (Style)dg.FindResource("s");
for (int i = 0; i < dg.Items.Count; i++)
{
DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
if (row == null) // May be virtualized, bring into view and try again.
{
dg.UpdateLayout();
dg.ScrollIntoView(dg.Items[i]);
row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
}
TextBlock tb = (TextBlock)c.GetCellContent(row);
Binding binding = BindingOperations.GetBinding(tb, TextBlock.TextProperty);
binding.ValidationRules.Clear();
binding.ValidationRules.Add(new VR());
}
}
}
}
public class VR : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
...
}
}
EDIT: updated XAML code according to dev hedgehog's suggestion, still not working.