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

本文关键字:集合 验证 | 更新日期: 2023-09-27 18:26:59

我正在使用MVVM在C#/WPF中处理一个项目。表达我的问题的简化方案如下:

有一个 Person 类,它具有类型 stringName 属性。然后,House类包含Person对象的ObservableCollection(称为People(。House中的Person实例不允许具有相同的Name,因此每当将Person添加到集合中时,都会进行检查。

在 WPF 中,我有一个带有ItemTemplateListBox,其中包含绑定到每个Person (TwoWay( 的NameTextBox,因此用户可以更改它。

问题是,如何对整个集合执行验证,以检查其他人是否已经拥有用户输入的名称?

更新:

所以我正在尝试为此使用自定义ValidationRule,我需要将集合作为参数传递。事实上,我需要传递保存集合(ListBoxDataContext(和进行验证的Person的 ViewModel。

因此,在这篇文章之后,我有一个从ValidationRule派生的MyValidationRule对象,它具有 PersonValidationContext 类型的属性。PersonValidationContext类派生自FrameworkElement,具有两个DependencyProperty属性,一个用于 ViewModel,另一个用于当前人员。

正如 H.B. 在提到的帖子中所回答的那样,绑定到ListBox的解决方法是使用 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>

因此,这适用于传递视图模型。但是,Person绑定始终指向集合中的第一项(即第一个Person(。有谁知道这件事吗?关于如何绑定到所选项目的任何建议?

此外,每当更新一个人时,我都会尝试对所有人的Name进行强制验证,以确保正确的行为(考虑如果用户将 Person1 的名称更改为与 Person2 相同的名称,则会出现验证错误,然后用户将 Person2 的名称更改为其他名称,错误不会像应有的那样消失(。

任何指示将不胜感激!

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

设计

对象不知道它是集合的成员。 如果你想要对集合的引用,你需要传递它。 但是,您可以有一个构造函数传递父集合,而另一个不传递父集合。 如果父集合为 null,则只需不检查重复项。