我正在使用MVVM在C#/ WPF中开展一个项目。 表达我的问题的简化方案如下:
有一个Person
类,其Name
属性类型为string
。
然后,House
类包含ObservableCollection
个Person
个对象(称为People
)。
Person
中的House
个实例不允许具有相同的Name
,因此每当Person
添加到集合时都会进行检查。
在WPF中,我有一个ListBox
,ItemTemplate
包含TextBox
,Name
绑定到每个Person
的{{1}}(TwoWay),所以用户可以更改它。
问题是,如何对整个集合进行验证,检查另一个人是否已经拥有用户输入的名称?
更新:
所以我尝试使用自定义ValidationRule
,我需要将集合作为参数传递。实际上,我需要传递ViewModel,它包含要进行验证的集合(DataContext
的{{1}})和ListBox
。
因此,在发布this后,我有一个Person
对象派生自MyValidationRule
,其属性类型为ValidationRule
。 PersonValidationContext
类派生自PersonValidationContext
并具有两个FrameworkElement
属性,一个用于ViewModel,另一个用于当前Person。
正如前面提到的帖子中H.B.所回答的那样,绑定到DependencyProperty
的解决方法是使用ListBox
,因为验证规则不是可视树的一部分。毕竟我有
x:Reference
所以这就像传递ViewModel一样。但是,<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
时强制验证,以确保正确的行为(考虑用户是否将Person1的名称更改为与Person2相同的名称,验证错误出现,然后用户将Person2的名称更改为不同的名称,错误不会消失,因为它应该)。
任何指针都将非常感谢!
答案 0 :(得分:0)
设计对象不知道它是集合的成员。如果您想要对集合的引用,则需要传递它。但是你可以有一个传递父集合的构造函数,而另一个不传递。如果父集合为null,则只是不检查重复项。