Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 针对整个集合验证集合项以防止重复_C#_Wpf_Validation - Fatal编程技术网

C# 针对整个集合验证集合项以防止重复

C# 针对整个集合验证集合项以防止重复,c#,wpf,validation,C#,Wpf,Validation,我正在使用MVVM在C#/WPF中进行一个项目。 表达我的问题的简化场景如下: 有一个Person类,它具有类型为string的Name属性。 然后一个House类持有Person对象(称为People)的可观察集合。 House中的Person实例不允许具有相同的名称,因此每当向集合中添加Person时都会进行检查 在WPF中,我有一个列表框,其中包含一个文本框,该文本框绑定到每个人的姓名(双向),因此用户可以更改它 问题是,如何对整个集合执行验证,以检查另一个人是否已经拥有用户输入的名称 更

我正在使用MVVM在C#/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
似乎是一条出路。你能提供更多关于你尝试了什么以及为什么失败的细节吗?示例代码?例外还是不正确的行为?是的,我也是这么想的。有关更新的示例代码,请参见问题。