ValidateItemsInItemsControl在ItemsControl中的验证项处理
该应用程序提示用户输入多个客户,并为每个客户指定一个销售代表。 该应用程序检查销售代表和客户是否属于同一区域。 如果所有验证规则都成功,则该示例将调用 UpdateSources 来验证绑定并将值保存到源。
实现效果:
- 进行一项组件Customers的数据(地区与对应代理)验证,并显示错误提示。
- 对再添加一项组件进行数据验证,并显示验证错误信息框提示。
练习:
- ItemsControl.ItemBindingGroup 属性
- ComboBox的itemsSource绑定与SelectedItem绑定
- Validation.ValidationAdornerSite
数据源xaml
类型作为方法参数值的表示如下:
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="RegionValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:Region" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:Representantives x:Key="SaleReps"/>
复杂的数据模板如下:
<DataTemplate x:Key="ItemTemplate" >
<StackPanel Orientation="Horizontal" >
<TextBlock Text="Customer Name" Margin="5"/>
<TextBox Width="100" Margin="5" Text="{Binding Name}"/>
<TextBlock Text="Region" Margin="5"/>
<ComboBox ItemsSource="{Binding Source={StaticResource RegionValues}}"
SelectedItem="{Binding Location}" Width="100" Margin="5"/>
<TextBlock Text="Service Representative" Margin="5"/>
<ComboBox ItemsSource="{Binding Source={StaticResource SaleReps}}"
SelectedItem="{Binding ServiceRepresentative}" Width="200" Margin="5"/>
<Button Content="Save Customer" Click="saveCustomer_Click"/>
</StackPanel>
</DataTemplate>
ItemsControl作为可添加元素的控件如下:
其中Validation.ValidationAdornerSite 和Validation.ValidationAdornerSiteFor 附加属性相互引用,您可以设置其中任一属性。例如,假设 Label 显示数据绑定 TextBox 上发生的验证错误。 可以执行下列操作之一来建立该关系:
- 将 TextBox 的 Validation.ValidationAdornerSite 设置为 Label。
- 将 Label 的 Validation.ValidationAdornerSiteFor 设置为 TextBox。
当设置其中一个属性时,另一个属性会设置为您在其上设置附加属性的元素;无论您选择前面哪个选项, TextBox 的 Validation.ValidationAdornerSite 均为 Label,且 Label 的 ValidationAdornerSiteFor 均为 TextBox。
<ItemsControl Margin="5" Name="customerList" ItemTemplate="{StaticResource ItemTemplate}"
ItemsSource="{Binding}">
<ItemsControl.ItemBindingGroup>
<BindingGroup>
<BindingGroup.ValidationRules>
<local:AreasMatch/>
</BindingGroup.ValidationRules>
</BindingGroup>
</ItemsControl.ItemBindingGroup>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Validation.ValidationAdornerSite"
Value="{Binding ElementName=validationErrorReport}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<Label Name="validationErrorReport"
Content="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)[0].ErrorContent}"
Margin="5" Foreground="Red" HorizontalAlignment="Center"/>
思路:
- 在ItemTemplate中处理要模型类Customer的属性数据绑定,其中有ComboBox显示枚举类型及SelectedItem的数据绑定。
- 在ItemsControl中进行ItemBindingGroup,进行item的模型类属性间的匹配验证;当点击保存按钮时进行数据验证:当其中一项验证成功后可添加下一项,或多项中只要有一项验证错误就进行提示,不可再添加项。(此示例有bug,在未选择ComboBox数据时进行验证程序崩溃)
- 添加按钮进行添加项,同时进行数据验证。
private void saveCustomer_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
var container = (FrameworkElement) customerList.ContainerFromElement(btn);
// If the user is trying to change an items, when another item has an error,
// display a message and cancel the currently edited item.
if (_bindingGroupInError != null && _bindingGroupInError != container?.BindingGroup)
{
MessageBox.Show("Please correct the data in error before changing another customer");
container.BindingGroup.CancelEdit();
return;
}
if (container.BindingGroup.ValidateWithoutUpdate())
{
container.BindingGroup.UpdateSources();
_bindingGroupInError = null;
MessageBox.Show("Item Saved");
}
else
{
_bindingGroupInError = container.BindingGroup;
}
}
以上代码进行保存时进行数据验证,具体步骤如下:
- 找到拥有当前项的ItemsControl,判断验证集合BindingGroup _bindingGroupInError若出现有ItemsControl的验证错误信息,就显示里面的项有验证错误,提示后进行container.BindingGroup.CancelEdit();
- 若验证成功,则此方法将更新源,但不会使源提交挂起的更改并结束编辑事务。 也就是说,如果源对象实现 IEditableObject, 则调用此方法时不会调用 EndEdit。 若要使源提交挂起的更改,请使用 CommitEdit 方法。
private void AddCustomer_Click(object sender, RoutedEventArgs e)
{
if (_bindingGroupInError == null)
{
_customerData.Add(new Customer());
}
else
{
MessageBox.Show("Please correct the data in error before adding a new customer.");
}
}
扩展:
- BindingGroup.ValidateWithoutUpdate 方法:对绑定和将 ValidationStep 属性设置为 RawProposedValue 或 ConvertedProposedValue 的 ValidationRule 对象运行转换器。如果验证规则成功,则为 true;否则为 false。
- 则该示例将调用 UpdateSources 来验证绑定并将值保存到源。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。