Обнаружение ошибок проверки WPF

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

114
задан Hossein Narimani Rad 22 April 2015 в 11:17
поделиться

7 ответов

Следующий код (от Программирования WPF заказывают Chris Sell & Ian Griffiths), проверяет все обязательные правила об объекте зависимости и его детях:

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;
    }

}

можно назвать это в обработчике событий нажатия кнопки сохранения как это на странице/окне

private void saveButton_Click(object sender, RoutedEventArgs e)
{

  if (Validator.IsValid(this)) // is valid
   {

    ....
   }
}
47
ответ дан aogan 24 November 2019 в 02:33
поделиться

Отправленный код не работал на меня при использовании 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;
}
32
ответ дан H-Man2 24 November 2019 в 02:33
поделиться

Можно выполнить итерации по всему дереву средств управления рекурсивно и проверить приложенное свойство Validation. HasErrorProperty, затем сфокусируйтесь на первом, который Вы находите в нем.

можно также использовать много уже записанных решений, которые можно проверить этот поток для примера и большей информации

0
ответ дан user21243 24 November 2019 в 02:33
поделиться

В форме ответа aogan вместо явной итерации по правилам проверки лучше просто вызвать выражение.UpdateSource ():

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;
    }
}
0
ответ дан 24 November 2019 в 02:33
поделиться

Если бы та же проблема и попробовал предоставленные решения. Комбинация решений H-Man2 и skiba_k сработала для меня почти нормально, за одним исключением: в моем окне есть TabControl. И правила проверки оцениваются только для видимого в данный момент элемента TabItem. Поэтому я заменил VisualTreeHelper на LogicalTreeHelper. Теперь это работает.

    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;
    }
16
ответ дан 24 November 2019 в 02:33
поделиться

Я бы предложил небольшую оптимизацию.

Если вы проделаете это много раз для одних и тех же элементов управления, вы можете добавить приведенный выше код, чтобы сохранить список элементов управления, которые действительно имеют правила проверки. Затем всякий раз, когда вам нужно проверить правильность, просматривайте только эти элементы управления, а не все визуальное дерево. Было бы намного лучше, если бы у вас было много таких элементов управления.

2
ответ дан 24 November 2019 в 02:33
поделиться

Возможно, вас заинтересует пример приложения BookLibrary WPF Application Framework (WAF) . В нем показано, как использовать проверку в WPF и как управлять кнопкой «Сохранить» при наличии ошибок проверки.

0
ответ дан 24 November 2019 в 02:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: