我正在尝试在出现验证错误时更改DataGridCell的默认样式(在WPF Toolkit DataGrid中)。默认为红色边框。我怎样才能放置自己的模板?
感谢。
答案 0 :(得分:9)
试试这个:
<!-- 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>
答案 1 :(得分:2)
Diederik Krols有一个nice tutorial,它完全符合您对WPF Toolkit DataGrid的要求。
答案 2 :(得分:0)
下面是一种解决方案,但首先,让我分享我的发现。
似乎验证错误从未到达列的ElementStyle或CellStyle内部。我怀疑这是因为它到达并可以在列的EditingElementStyle和数据网格的RowStyle中使用。
例如,您可以根据Validation.HasError设置样式:
<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>
或者您也可以设置Validation.ErrorTemplate:
<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>
,两者都很好。在EditingElementStyle上相同。这些都不是真正解决问题的方法:更改行样式显然不会显示错误所在的单元格,并且一旦文本框散焦后就看不到编辑样式。
不幸的是,由于某种原因,相同的方法在ElementStyle或CellStyle上不起作用。我倾向于相信这是一个错误,因为在this tutorial中,它显示了在示例中设置Validation.HasError触发的样式,并显示在EditingElementStyle上:
您可以通过替换以下内容来实现更广泛的自定义 列使用的CellStyle。
一种解决方法是不使用触发器,而是将单元格的背景(或所需的任何样式属性)绑定到数据对象的新属性。我会明白我的意思。
在此示例中,有一些产品,它们具有一个类别,该类别将显示在数据网格的文本列中。这是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));
}
}
显然,此解决方案的巨大缺点是,它需要为数据对象中的每个属性提供一个(或更多,如果您需要更复杂的样式)样式属性,并且需要对这些属性进行许多手动设置。但这仍然是一种解决方案。