C# 针对整个集合验证集合项以防止重复
我正在使用MVVM在C#/WPF中进行一个项目。 表达我的问题的简化场景如下: 有一个C# 针对整个集合验证集合项以防止重复,c#,wpf,validation,C#,Wpf,Validation,我正在使用MVVM在C#/WPF中进行一个项目。 表达我的问题的简化场景如下: 有一个Person类,它具有类型为string的Name属性。 然后一个House类持有Person对象(称为People)的可观察集合。 House中的Person实例不允许具有相同的名称,因此每当向集合中添加Person时都会进行检查 在WPF中,我有一个列表框,其中包含一个文本框,该文本框绑定到每个人的姓名(双向),因此用户可以更改它 问题是,如何对整个集合执行验证,以检查另一个人是否已经拥有用户输入的名称 更
Person
类,它具有类型为string
的Name
属性。
然后一个House
类持有Person
对象(称为People
)的可观察集合。
House
中的Person
实例不允许具有相同的名称
,因此每当向集合中添加Person
时都会进行检查
在WPF中,我有一个列表框
,其中包含一个文本框
,该文本框绑定到每个人的姓名
(双向),因此用户可以更改它
问题是,如何对整个集合执行验证,以检查另一个人是否已经拥有用户输入的名称
更新:
因此,我尝试使用自定义的ValidationRule
,其中我需要将集合作为参数传递。事实上,我需要传递保存集合的ViewModel(ListBox
的DataContext
)和进行验证的Person
因此,在后面的文章中,我有一个从ValidationRule
派生的MyValidationRule
对象,它的属性类型为PersonValidationContext
。PersonValidationContext
类派生自FrameworkElement
,具有两个DependencyProperty
属性,一个用于ViewModel,另一个用于当前人员
正如在文章中提到的,绑定到列表框
的一个解决方法是使用x:Reference
,因为验证规则不是可视化树的一部分。所以毕竟我有
<ListBox Name="personsList"
ItemsSource="{Binding People}"
Margin="0,0"
BorderThickness="0"
SelectionMode="Single">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="Name: " Grid.Column="0" />
<TextBox x:Name="nameTextBox" Grid.Column="1">
<TextBox.Text>
<Binding Path="Name" Mode="TwoWay" NotifyOnValidationError="True"
ValidatesOnExceptions="True" ValidatesOnDataErrors="True"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<valid:MyValidationRule ValidatesOnTargetUpdated="True">
<valid:MyValidationRule.ValidationContext>
<valid:PersonValidationContext ViewModel="{Binding
Source={x:Reference Name=personsList},
Path=DataContext}"
Person="{Binding Source={x:Reference
Name=personsList}, Path=Items/}"/>
</valid:MyValidationRule.ValidationContext>
</valid:MyValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
因此,这在传递ViewModel时起作用。但是,Person
绑定始终指向集合中的第一项(即第一个Person
)。有人知道这件事吗?对如何绑定到所选项目有何建议
此外,每当更新一个人的姓名时,我都试图强制对其进行验证,以确保行为正确(考虑如果用户将Person1的姓名更改为与Person2相同的姓名,则会出现验证错误,然后用户将Person2的姓名更改为不同的名称,错误不会消失)
任何指点都将不胜感激 设计的对象不知道它是集合的成员。如果希望引用集合,则需要传递它。但是,可以有一个构造函数传递父集合,另一个构造函数不传递。如果父集合为null,则不检查重复项 您的要求是,如果人员
集合的任何其他成员具有相同的名称,则人员
类不得接受新的名称
值。除非Person
或验证代码能够直接或间接访问该人员集合,否则无法满足要求。自定义的ValidationRule
似乎是一条出路。你能提供更多关于你尝试了什么以及为什么失败的细节吗?示例代码?例外还是不正确的行为?是的,我也是这么想的。有关更新的示例代码,请参见问题。