我想要更改DataGridCell(WPF Toolkit DataGrid中的单元格)在验证错误时的默认样式,它默认为红色边框。请问我如何使用自己的模板?
谢谢。
谢谢。
试试这个:
<!-- Cell Style -->
<Style x:Key="CellErrorStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="Background" Value="Yellow"/>
</Trigger>
</Style.Triggers>
</Style>
并使用它:
<DataGrid.Columns>
<DataGridTextColumn
ElementStyle="{StaticResource CellErrorStyle}">
</DataGridTextColumn>
</DataGrid.Columns>
这里有一篇来自Diederik Krols的不错的教程,它能够完全满足你对WPF Toolkit DataGrid的要求。
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Red" BorderThickness="3">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
两种方法都可以正常工作。编辑元素样式也是一样。但是这两种方法都不能解决问题:更改行样式显然不能显示出错误所在的单元格,而编辑样式一旦文本框失去焦点就不可见了。
不幸的是,由于某些原因,同样的方法在ElementStyle或CellStyle上不起作用。我倾向于认为这是一个bug,因为在this tutorial中,在展示设置Validation.HasError触发样式在EditingElementStyle上的示例后,它说:
您可以通过替换列使用的CellStyle来实现更广泛的自定义。
一种解决方法是不使用触发器,而是将单元格的背景(或任何样式属性)绑定到数据对象的新属性上。我会展示我的意思。
在这个例子中,有产品,它们有一个类别,将在datagrid中显示为文本列。以下是XAML:
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Products}">
<DataGrid.Columns>
<!-- other columns -->
<DataGridTextColumn Header="Category">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background"
Value="{Binding Mode=OneWay, Path=CategoryErrorBackgroundColor}" />
</Style>
</DataGridTextColumn.CellStyle>
<DataGridTextColumn.Binding>
<Binding Path="Category" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
</Binding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
<!-- other columns -->
</DataGrid.Columns>
</DataGrid>
以下是Product类的代码:
public class Product : INotifyPropertyChanged
{
// ...other fields and properties
private string category;
private SolidColorBrush categoryErrorBackgroundColor;
public string Category
{
get
{
return category;
}
set
{
// validation checks
if (value.Lenght < 5)
{
CategoryErrorBackgroundColor = Brushes.Red;
// Notice that throwing is not even necessary for this solution to work
throw new ArgumentException("Category cannot be shorter than 5 characters.");
}
else
{
CategoryErrorBackgroundColor = Brushes.Transparent;
}
category = value;
}
}
// This is the property I'm binding to the cell's background
// It has to have the appropriate type
public SolidColorBrush CategoryErrorBackgroundColor
{
get
{
return categoryErrorBackgroundColor;
}
set
{
categoryErrorBackgroundColor = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}