Я недавно использовал код из этого предыдущего ответа SO Обнаружение ошибок проверки WPF , чтобы получить именно этот эффект.
У меня есть пользовательский элемент управления, который содержит DataGrid.Usercontrol предоставляет свойство IsValid
, которое содержит метод получения, который просто вызывает статическую функцию IsValid, передающую DataGrid как DependencyObject:
public class MyControl : UserControl
{
public bool IsValid
{
get { return Validator.IsValid(MyDataGrid); }
}
}
Свойство IsValid
элемента управления может быть затем проверено CanExecuteФункция команды, которую вы привязываете к кнопке, которую вы хотите включить / отключить.
Моя единственная проблема с кодом, на который я ссылался, заключалась в том, что он фактически оценивает проверки на привязках, это означает, что как только вы запуститеесли любое поле, которое является технически недействительным, но еще не было признано недействительным (т. е. пользователь, возможно, еще не ввел никаких данных в это поле, потому что они не дошли до него), теперь будет в недопустимом состоянии - я еще не сделалМы рассмотрели способ избежать или смягчить это.
Редактировать:
Вот обновленная версия, которая не делает недействительными элементы управления, как я упоминал ранее.Я просто закомментировал / немного изменил некоторые строки, но оставил все там, чтобы вы могли увидеть разницу.Обратите внимание, что это также должно выполняться быстрее, так как вы будете выходить, как только найдете первую недействительную привязку.
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;
}