WPF入门教程系列五——Window 介绍
DataGrid 控件可以在单元格级别和行级别执行验证。 通过单元格级别验证,可以在用户修改单元的数据时验证绑定数据对象的单个属性。 通过行级别验证,可以在用户提交对行的更改时验证整行对象的数据。 还可以提供针对验证错误的自定义可视化反馈,或使用 DataGrid 控件提供的默认可视化反馈。
今天通过下面的示例学习如何将验证规则应用于 DataGrid 绑定并自定义可视化错误信息提示。
1. 在Visual Studio 2022的“解决方案资源管理器”中,使用鼠标右键单击“WpfGridDemo.NET7”项目,在弹出菜单中选择“添加–>新建文件夹”。 并将“新文件夹”改名为 “Vali”。
2. 在Visual Studio 2022的解决方案资源管理器中,使用鼠标右键单击“Vali”文件夹,在弹出菜单中选择“添加–> 类”,在弹出的“添加新项”对话框中,选择添加 “AreaValidationRule”类,这是一个我们要实现的验证类,然后选择“添加”。
3.要实现在自定交验证规则,则必须继承ValidationRule类,并重写Validate方法,下面就是具体实现代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using WpfGridDemo.NET7.Entitys; namespace WpfGridDemo.NET7.Vali { public class AreaValidationRule: ValidationRule { public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { Area course = (value as BindingGroup).Items[0] as Area; if (course.Created > course.Updated) { return new ValidationResult(false, "创建日期必须小于等于更新日期。"); } else { return ValidationResult.ValidResult; } } } }
DataGrid.Resources>
Style x:Key="errorStyle" TargetType="{x:Type TextBox}">
Setter Property="Padding" Value="-2"/>
Style.Triggers>
Trigger Property="Validation.HasError" Value="True">
Setter Property="Background" Value="Red"/>
Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
Trigger>
Style.Triggers>
Style>
DataGrid.Resources>
5. 对DataGrid的DataGridTextColumn 绑定错误提示信息样式,设置ValidatesOnExceptions属性为true,此属性提供了显式使用元素的 ExceptionValidationRule替代方法。 ExceptionValidationRule是一个内置验证规则,用于检查在更新源属性期间引发的异常。
DataGridTextColumn Header="ID" Width="100" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Id ,ValidatesOnExceptions=True}" ClipboardContentBinding="{x:Null}"/>
6.在Visual Studio 2022中按F5键,启动WPF应用程序。然后使用鼠标点击省份下拉框,界面中DataGrid中的呈现了城市与县区镇数据。
请尝试以下操作:
- 在“ID”列中输入一个非整数值。
- 删除“ID”的值。
你会发现,删除或是填了非整数值的那个单元格变成了红色,鼠标移到到其他单元格,也无法进入编辑模式。如下图。
7. 移动鼠标,将光标置入到红色的单元格中,然后按 ESC 键,应用程序自动撤消了无效的单元格值。如下图。
8.在Visual Studio 2022中打开MainWindows.xmal文件,并在文件的开头添加如下命名空间。
xmlns:vl="clr-namespace:WpfGridDemo.NET7.Vali"
9. 将之前创建的验证规则AreaValidationRule添加到 DataGrid.RowValidationRules 集合中。 以便通过 RowValidationRules 属性直接访问 BindingGroup 实例的 ValidationRules 属性,该实例对控件使用的所有绑定进行分组。
DataGrid.RowValidationRules>
vl:AreaValidationRule ValidationStep="UpdatedValue"/>
DataGrid.RowValidationRules>
10. 通过设置 DataGrid.RowValidationErrorTemplate 属性,自定义各个 DataGrid 控件的行验证时的错误提示。 还可以使用隐式行样式设置 DataGridRow.ValidationErrorTemplate 属性来影响多个控件。
当用户输入无效值,行标题中将显示带有白色感叹号的红色圆圈。 行和单元格验证错误时都将发生这种情况。 关联的错误消息将显示在工具提示中。
DataGrid.RowValidationErrorTemplate>
ControlTemplate>
Grid Margin="0,-2,0,-2"
ToolTip="{Binding RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type DataGridRow}},
Path=(Validation.Errors)[0].ErrorContent}">
Ellipse StrokeThickness="0" Fill="Red"
Width="{TemplateBinding FontSize}"
Height="{TemplateBinding FontSize}" />
TextBlock Text="!" FontSize="{TemplateBinding FontSize}"
FontWeight="Bold" Foreground="White"
HorizontalAlignment="Center" />
Grid>
ControlTemplate>
DataGrid.RowValidationErrorTemplate>
11. 对DataGrid的DataGridTextColumn 绑定错误提示信息样式,设置ValidatesOnExceptions属性为true,此属性提供了显式使用元素的 ExceptionValidationRule替代方法。 ExceptionValidationRule是一个内置验证规则,用于检查在更新源属性期间引发的异常。
DataGridTextColumn Header="创建时间" Width="160" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Created ,ValidatesOnExceptions=True,StringFormat=s}" ClipboardContentBinding="{x:Null}"/>
DataGridTextColumn Header="更新时间" Width="160" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Updated,ValidatesOnExceptions=True,StringFormat=s}" ClipboardContentBinding="{x:Null}"/>
12. 在Visual Studio 2022中按F5键,启动WPF应用程序。然后使用鼠标点击省份下拉框,界面中DataGrid中的呈现了城市与县区镇数据。
请尝试以下操作:
- 在“创建时间”列中输入一个早于更新时间的日期。
- 删除“创建时间”或是“更新时间”单元格中的值
你会发现,删除了日期的那个单元格变成了红色,鼠标移到到其他单元格,也无法进入编辑模式。
你会发现,在行的行头中将显示一个红色感叹号 (!),将鼠标指针移到行标题中的标记上,以查看关联的错误消息。
如下图。
13.MainWindow.xmal的全部代码如下:
Window x:Class="WpfGridDemo.NET7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:be="http://schemas.microsoft.com/xaml/behaviors"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfGridDemo.NET7"
xmlns:v="clr-namespace:WpfGridDemo.NET7.ViewModel"
xmlns:vl="clr-namespace:WpfGridDemo.NET7.Vali"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="960" Loaded="Window_Loaded" >
Grid>
Grid.RowDefinitions>
RowDefinition Height="100">RowDefinition>
RowDefinition Height="*">RowDefinition>
RowDefinition Height="25">RowDefinition>
Grid.RowDefinitions>
WrapPanel Grid.Row="0" HorizontalAlignment="Left">
ComboBox x:Name="cboProvince" DisplayMemberPath="Name" SelectedValuePath="Code" >
be:Interaction.Triggers>
be:EventTrigger EventName="SelectionChanged">
be:InvokeCommandAction Command="{Binding ProviceChangedAction}"
CommandParameter="{Binding ElementName=cboProvince}"/>
be:EventTrigger>
be:Interaction.Triggers>
ComboBox>
WrapPanel>
DataGrid x:Name="gridArea" Grid.Row="1" ItemsSource="{Binding GridAreaList}"
AutoGenerateColumns="False" HorizontalAlignment="Left" VerticalAlignment="Top" SelectedItem="{Binding Path=AreaVM,
Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
DataGrid.Resources>
Style x:Key="errorStyle" TargetType="{x:Type TextBox}">
Setter Property="Padding" Value="-2"/>
Style.Triggers>
Trigger Property="Validation.HasError" Value="True">
Setter Property="Background" Value="Red"/>
Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
Trigger>
Style.Triggers>
Style>
DataGrid.Resources>
DataGrid.Columns>
DataGridComboBoxColumn Header="城市" Width="120" x:Name="cboCity"
ItemsSource="{x:Static v:MainWindowVM.GridCityList}"
ClipboardContentBinding="{x:Null}" SelectedValuePath="Code" SelectedValueBinding="{Binding Path=CityCode,
UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name" SelectedItemBinding="{x:Null}" />
DataGridComboBoxColumn Header="城市(Style)" SelectedValuePath="Code"
SelectedValueBinding="{Binding Path=CityCode,UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name" SelectedItemBinding="{x:Null}" Width="1*">
DataGridComboBoxColumn.EditingElementStyle>
Style TargetType="ComboBox">
Setter Property="ItemsSource" Value="{Binding Path=DataContext.GridCity,ElementName=gridArea}" />
Style>
DataGridComboBoxColumn.EditingElementStyle>
DataGridComboBoxColumn.ElementStyle>
Style TargetType="ComboBox">
Setter Property="ItemsSource" Value="{Binding Path=DataContext.GridCity,ElementName=gridArea}" />
Style>
DataGridComboBoxColumn.ElementStyle>
DataGridComboBoxColumn>
DataGridTextColumn Header="县区镇" Width="*" Binding="{Binding Name}" ClipboardContentBinding="{x:Null}"/>
DataGridTextColumn Header="邮编" Width="100" Binding="{Binding Code}" ClipboardContentBinding="{x:Null}"/>
DataGridTextColumn Header="ID" Width="100" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Id ,ValidatesOnExceptions=True}" ClipboardContentBinding="{x:Null}"/>
DataGridTextColumn Header="创建时间" Width="160" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Created ,ValidatesOnExceptions=True,StringFormat=s}" ClipboardContentBinding="{x:Null}"/>
DataGridTextColumn Header="更新时间" Width="160" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Updated,ValidatesOnExceptions=True,StringFormat=s}" ClipboardContentBinding="{x:Null}"/>
DataGrid.Columns>
DataGrid.RowValidationRules>
vl:AreaValidationRule ValidationStep="UpdatedValue"/>
DataGrid.RowValidationRules>
DataGrid.RowValidationErrorTemplate>
ControlTemplate>
Grid Margin="0,-2,0,-2"
ToolTip="{Binding RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type DataGridRow}},
Path=(Validation.Errors)[0].ErrorContent}">
Ellipse StrokeThickness="0" Fill="Red"
Width="{TemplateBinding FontSize}"
Height="{TemplateBinding FontSize}" />
TextBlock Text="!" FontSize="{TemplateBinding FontSize}"
FontWeight="Bold" Foreground="White"
HorizontalAlignment="Center" />
Grid>
ControlTemplate>
DataGrid.RowValidationErrorTemplate>
DataGrid>
WrapPanel Grid.Row="2">
Button x:Name="btnRefresh" Height="22" Width="120" Click="btnRefresh_Click">刷新Button>
Button x:Name="btnSave" Height="22" Width="120" Command="{Binding ClickSaveAction}" >保存Button>
WrapPanel>
Grid>
Window>
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 云原生开源项目CNSI(Narrows)v0.4发布
云原生安全开源项目CNSI(项目代号:Narrows)发布了0.4版本,新增了“cnsi-scanner-trivy”的组件,帮助用户更容易的进行工作负载的漏洞扫描。使用该组件也可以非常方便的进行镜像内软件包漏洞、错误配置和license信息的扫描。除此之外,…