GetLocalValueEnumerator () не возвращает все свойства - PullRequest
4 голосов
/ 03 декабря 2008

Я пытаюсь выполнить проверку в своем приложении WPF, используя решение в Обнаружение ошибок проверки WPF .

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

Проблема, с которой я сталкиваюсь, заключается в том, что, когда я перебираю код для TextBox, я не получаю свойство Text. Я получаю только свойства PageHeight, Instance и UndoManagerInstance. Поэтому я не могу проверить правила для привязки на TextBox.

Кто-нибудь знает, почему я не могу получить правильные свойства? Есть ли другой способ принудительной проверки достоверности элементов управления в WPF? Я не смог найти никого другого, у кого была эта проблема.

Обновление: TextBoxes, которые я пытаюсь проверить, находятся в DataTemplate. Я обнаружил, что если я скопирую один из текстовых полей и поместлю его прямо в окно, я смогу получить данные. Используя Woodstock, я увидел, что источником данных для TextBoxes в шаблоне является «ParentTemplate», но «Text» для TextBox за пределами шаблона.

Итак, вопрос теперь в том, как я могу получить свойства DependencyProperties для элементов управления внутри a DataTemplate?

1 Ответ

5 голосов
/ 10 января 2011

Это более двух лет, но недавно я боролся с той же проблемой, используя тот же метод.

Мое решение этой проблемы состоит в том, чтобы получить все свойства DependencyProperties объекта с использованием отражения вместо использования GetLocalValueEnumerator, который не работает в основном с DataTemplates.

Код:

    public static bool IsValid(DependencyObject parent)
    {
        // Validate all the bindings on the parent        
        bool valid = true;
        var infos = parent.GetType().GetFields(
                        BindingFlags.Public
                        | BindingFlags.FlattenHierarchy
                        | BindingFlags.Instance
                        | BindingFlags.Static).Where(f => f.FieldType == typeof(DependencyProperty));
        foreach (FieldInfo field in infos)
        {
            var dp = (DependencyProperty)field.GetValue(null);
            if (BindingOperations.IsDataBound(parent, dp))
            {
                Binding binding = BindingOperations.GetBinding(parent, dp);
                foreach (ValidationRule rule in binding.ValidationRules)
                {
                    ValidationResult result = rule.Validate(parent.GetValue(dp), null);
                    if (!result.IsValid)
                    {
                        BindingExpression expression = BindingOperations.GetBindingExpression(parent, dp);
                        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;
    }

Этот код работает только со свойствами, принадлежащими объекту, чтобы расширить его для прикрепленных свойств. Вы можете использовать этот код:

    public static List<DependencyProperty> GetAttachedProperties(Object element)
    {
        List<DependencyProperty> attachedProperties = new List<DependencyProperty>();
        System.Windows.Markup.Primitives.MarkupObject markupObject = 
            System.Windows.Markup.Primitives.MarkupWriter.GetMarkupObjectFor(element);
        if (markupObject != null)
        {
            foreach (System.Windows.Markup.Primitives.MarkupProperty mp in markupObject.Properties)
            {
                if (mp.IsAttached)
                {
                    attachedProperties.Add(mp.DependencyProperty);
                }
            }
        }

        return attachedProperties;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...