有没有办法确定ItemsControl是否有任何带有验证错误的子控件?我想将此值(布尔值)绑定到Button上的IsEnabled属性。
答案 0 :(得分:0)
我最近使用了之前的SO回答 Detecting WPF Validation Errors 中的代码,这对此非常有效。
我有一个包含DataGrid的用户控件。 usercontrol公开一个包含getter的IsValid
属性,它只是调用静态IsValid函数作为DependencyObject传入DataGrid:
public class MyControl : UserControl
{
public bool IsValid
{
get { return Validator.IsValid(MyDataGrid); }
}
}
然后可以通过绑定到要启用/禁用的按钮的命令的CanExecute函数来检查控件的IsValid
属性。
我链接的代码的唯一问题是它实际上评估了绑定的验证,这意味着只要你运行任何技术上无效但尚未失效的字段(即用户可能尚未输入该字段中的任何数据,因为他们没有得到它)现在将处于无效状态 - 我还没有找到避免或减轻这种情况的方法。
修改强>
这是一个更新版本,不会像我之前提到的那样使控件无效。我只是评论出来/略微改变了一些线条,但是把所有东西留在那里,这样你就能看出差异。请注意,这也应该更快,因为您将在找到第一个无效绑定时退出。
public static bool IsValid(DependencyObject parent)
{
// Validate all the bindings on the parent
bool valid = true;
LocalValueEnumerator localValues = parent.GetLocalValueEnumerator();
while (localValues.MoveNext())
{
LocalValueEntry entry = localValues.Current;
if (BindingOperations.IsDataBound(parent, entry.Property))
{
Binding binding = BindingOperations.GetBinding(parent, entry.Property);
foreach (ValidationRule rule in binding.ValidationRules)
{
ValidationResult result = rule.Validate(parent.GetValue(entry.Property), null);
if (!result.IsValid)
{
//BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property);
//System.Windows.Controls.Validation.MarkInvalid(expression, new ValidationError(rule, expression, result.ErrorContent, null));
//valid = false;
return false;
}
}
}
}
// Validate all the bindings on the children
for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (!IsValid(child))
{
//valid = false;
return false;
}
}
//return valid;
return true;
}
答案 1 :(得分:0)
我不知道为什么,slugter的答案对我不起作用(LocalValueEnumerator
返回了一些属性但从来没有绑定过,如Text
)。
我设法让它使用此代码(源自this answer):
public static bool IsValid(DependencyObject obj)
{
// The dependency object is valid if it has no errors,
//and all of its children (that are dependency objects) are error-free.
return !Validation.GetHasError(obj) &&
GetVisualTreeChildren(obj)
.OfType<DependencyObject>()
.All(child => IsValid(child));
}
//VisualTreeHelper don't have a method to get all the children of a visual object
private static IEnumerable GetVisualTreeChildren(DependencyObject parent)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
yield return VisualTreeHelper.GetChild(parent, i);
}