Kev*_*dge 114 data-binding validation wpf
在WPF中,您可以使用ExceptionValidationRule或在数据绑定期间根据数据层中抛出的错误设置验证DataErrorValidationRule.
假设你有一堆这样设置的控件,你有一个Save按钮.当用户单击"保存"按钮时,您需要确保在继续保存之前没有验证错误.如果存在验证错误,您希望对它们大声疾呼.
在WPF中,如何确定是否有任何数据绑定控件设置了验证错误?
小智 135
这篇文章非常有帮助.感谢所有贡献者.这是一个你会喜欢或讨厌的LINQ版本.
private void CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = IsValid(sender as DependencyObject);
}
private 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) &&
LogicalTreeHelper.GetChildren(obj)
.OfType<DependencyObject>()
.All(IsValid);
}
Run Code Online (Sandbox Code Playgroud)
aog*_*gan 47
以下代码(来自Chris Sell和Ian Griffiths的Programming WPF一书)验证了依赖对象及其子代的所有绑定规则:
public static class Validator
{
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;
}
}
}
}
// 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 valid;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在页面/窗口中的保存按钮单击事件处理程序中调用此方法
private void saveButton_Click(object sender, RoutedEventArgs e)
{
if (Validator.IsValid(this)) // is valid
{
....
}
}
Run Code Online (Sandbox Code Playgroud)
H-M*_*an2 32
使用ListBox时,发布的代码对我不起作用.我重写了它,现在它的工作原理:
public static bool IsValid(DependencyObject parent)
{
if (Validation.GetHasError(parent))
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)) { return false; }
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
小智 16
有同样的问题,并尝试提供的解决方案.H-Man2和skiba_k解决方案的组合对我来说几乎没问题,但有一个例外:My Window有一个TabControl.并且仅针对当前可见的TabItem评估验证规则.所以我用LogicalTreeHelper替换了VisualTreeHelper.现在它有效.
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);
if (binding.ValidationRules.Count > 0)
{
BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property);
expression.UpdateSource();
if (expression.HasError)
{
valid = false;
}
}
}
}
// Validate all the bindings on the children
System.Collections.IEnumerable children = LogicalTreeHelper.GetChildren(parent);
foreach (object obj in children)
{
if (obj is DependencyObject)
{
DependencyObject child = (DependencyObject)obj;
if (!IsValid(child)) { valid = false; }
}
}
return valid;
}
Run Code Online (Sandbox Code Playgroud)
小智 7
除了Dean的出色LINQ实现之外,我还很乐意将代码包装到DependencyObjects的扩展中:
public static bool IsValid(this DependencyObject instance)
{
// Validate recursivly
return !Validation.GetHasError(instance) && LogicalTreeHelper.GetChildren(instance).OfType<DependencyObject>().All(child => child.IsValid());
}
Run Code Online (Sandbox Code Playgroud)
考虑到重复使用,这非常好.
| 归档时间: |
|
| 查看次数: |
59292 次 |
| 最近记录: |