WPF中ListBox的数据验证

4

我有一个ListBox,它绑定了一个类型为T的ObservableCollection - 每个ListBoxItem都是一个复选框,其IsChecked属性绑定到T中的一个bool属性。我想要验证ListBox中被选中的项,以确保至少有一个复选框被选中 - 如果没有任何复选框被选中,我想在ListBox周围显示红色边框(标准验证通知)。

我该如何做呢?我可以使用ValidatesOnDataErrors吗?

2个回答

1
在公开 ObservableCollection<T> 属性的类中实现 IDataErrorInfo,并使索引器返回该属性名称的错误,如果集合中的所有对象在其布尔属性中具有 false 的值。然后在绑定的 ValidationRules 中使用 DataErrorValidationRule

1
我不确定你的意思。因为ObservableCollection<T>属性本身并没有改变,只有T中的值改变,所以IDataErrorInfo索引器从未被调用过。 - Paley
1
唉,你必须连接一些东西来在属性变为有效或无效时引发“PropertyChanged”。这有点麻烦。我会让集合所在的类监听集合中项目的“PropertyChanged”(假设它们引发了它;如果没有,那就更麻烦了),并在其中一个项目的“IsChecked”属性(无论它被命名为什么)更改时重新验证并引发自己的“PropertyChanged”事件。这样说清楚了吗? - Robert Rossney
某种程度上,我已经试图解决这个问题两周了。除了在文本框中之外,很少有关于验证的信息。我已经决定不再使用内置的验证机制,因为它太混乱且设计不良。感谢您的意见。 - Paley
你们考虑过采用什么替代方案吗?内置验证的哪一方面看起来不够合理呢?我认为棘手的问题在于当集合中的任何一个项更改时,需要作为整体对其进行验证。 - Robert Rossney

0

您的目标是验证 ListBox 中选择的项目:至少需要选择一个项目。首先,有不同的方法来处理选择本身:

a) 您可以使用 ListBox.SelectedItem 机制进行选择。 我猜想,您可以将绑定指定为 SelectedItem="{Binding SelectedThing, ValidatesOnNotifyDataErrors=True}",然后 WPF 的常规验证就会起作用。不确定这是否适用于多选。

b) 您可以使用 ListBox.SelectedItems。无法进行绑定,需要通过代码后台事件处理程序进行伪造。因此,WPF 的验证无法在此处触发。

c) 您可以使用自己的每个项目的 IsSelected 属性(或类似属性),可以通过 CheckBox 显式地绑定到您的视图模型,也可以通过 ListBoxItem.IsSelected 隐式地绑定(通过 ListBox.ItemContainerStyle)。

从这里开始,您可以在视图模型中创建一个bool IsValidSelection属性,每当选择更改时更新它。或者您可以对视图模型的任何结果属性(例如SelectedItems)运行验证规则。但是,您不会验证绑定的ListBox.ItemSource本身!因此,WPF的标准机制无法工作(列表框不会变成红色边框或其他什么)。

解决方法

您可以通过显示一个否则不可见的Label并将其可见性绑定到上述bool IsValidSelection属性来显式创建错误通知。这是一种非常明确的方式,根本不使用WPF验证。

您可以修改您的INotifyDataErrorInfo(或类似)实现,以触发不同属性名称上的错误。如果您使用通用的ValidatableViewModel<T>(像我一样),则无法实现此操作。我想这就是其他答案的意图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接