Wpf ValidationRule强制使用唯一名称

Wpf ValidationRule强制使用唯一名称,wpf,validation,data-binding,Wpf,Validation,Data Binding,我正在尝试编写一个自定义WPF ValidationRule,以强制规定某个属性在给定集合的上下文中是唯一的。例如:我正在编辑绑定到ListView的自定义对象集合,我需要确保集合中每个对象的Name属性都是唯一的。有人知道怎么做吗?首先,我要创建一个简单的DependencyObject类来保存您的收藏: class YourCollectionType : DependencyObject { [PROPERTY DEPENDENCY OF ObservableCollection

我正在尝试编写一个自定义WPF ValidationRule,以强制规定某个属性在给定集合的上下文中是唯一的。例如:我正在编辑绑定到ListView的自定义对象集合,我需要确保集合中每个对象的Name属性都是唯一的。有人知道怎么做吗?

首先,我要创建一个简单的DependencyObject类来保存您的收藏:

class YourCollectionType : DependencyObject {

    [PROPERTY DEPENDENCY OF ObservableCollection<YourType> NAMED: BoundList]

}
然后,在XAML中,执行以下操作:

<Binding.ValidationRules>
    <YourValidationRule>
       <YourValidationRule.ListToCheck>     
          <YourCollectionType BoundList="{Binding Path=TheCollectionYouWantToCheck}" />
       </YourValidationRule.ListToCheck>
    </YourValidationRule>
</Binding.ValidationRules>


然后在验证过程中,查看ListToCheck的BoundList属性的集合,以确定要验证的项。如果它在那里,显然返回一个错误的验证结果。如果不是,则返回true。

只有当有其他属性要绑定到规则时,我才会创建自定义依赖项对象。因为在本例中,我们所做的只是附加一个要检查的值集合,所以我将我的
属性设置为

从这里开始,为了克服
DataContext
没有被继承的问题,
需要有一个
来保存实际的绑定,并给它一个
{StaticResource}
键,
其他值
可以用作绑定源

然后,验证规则本身只需循环通过
OtherValues.Collection
,并执行相等性检查

注意:

    <TextBox>
        <TextBox.Resources>
            <CollectionViewSource x:Key="otherNames" Source="{Binding OtherNames}"/>
        </TextBox.Resources>
        <TextBox.Text>
            <Binding Path="Name">
                <Binding.ValidationRules>
                    <t:UniqueValueValidationRule>
                        <t:UniqueValueValidationRule.OtherValues>
                            <CollectionContainer Collection="{Binding Source={StaticResource otherNames}}"/>
                        </t:UniqueValueValidationRule.OtherValues>
                    </t:UniqueValueValidationRule>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>


这似乎不起作用,绑定结果总是空的(似乎不继承DataContext)。您是对的。ValidationRule不是可视树的一部分,因此不会继承DataContext。有一些很好的文章描述了这个问题和解决方案。
    <TextBox>
        <TextBox.Resources>
            <CollectionViewSource x:Key="otherNames" Source="{Binding OtherNames}"/>
        </TextBox.Resources>
        <TextBox.Text>
            <Binding Path="Name">
                <Binding.ValidationRules>
                    <t:UniqueValueValidationRule>
                        <t:UniqueValueValidationRule.OtherValues>
                            <CollectionContainer Collection="{Binding Source={StaticResource otherNames}}"/>
                        </t:UniqueValueValidationRule.OtherValues>
                    </t:UniqueValueValidationRule>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>