Получить все привязки данных из окна WPF - PullRequest
2 голосов
/ 27 августа 2010

У меня есть форма WPF, на которой много элементов управления. Многие (но не все) из этих элементов управления привязаны к базовому объекту. В определенные моменты времени, например, когда нажата кнопка «Сохранить», мне нужно проверить все правила проверки моих элементов управления. Есть ли способ сделать это программно, БЕЗ жесткого кодирования списка проверяемых элементов управления? Я хочу, чтобы это продолжало работать после того, как другой разработчик добавил еще один элемент управления и другую привязку, не обновляя список привязок для обновления.

В двух словах, есть ли способ получить коллекцию всех привязок данных из окна WPF?

Ответы [ 2 ]

5 голосов
/ 27 августа 2010

Попробуйте мой образец ниже. Я не полностью проверил это, поэтому у него могут быть проблемы. Кроме того, производительность может быть сомнительной. Может быть, другие могут помочь сделать это быстрее. Но, в любом случае, похоже, уловка.

Примечание. Тем не менее, ограничение заключается в том, что он может не захватывать привязки, определенные в Styles или DataTemplates. Я не уверен, хотя. Требуется больше испытаний.

В любом случае, решение состоит из трех частей:

  1. Используйте VisualTreeHelper для обхода всего визуального дерева.
  2. Для каждого элемента в визуальном дереве получить все свойства зависимостей. Reference .
  3. Используйте BindingOperations.GetBindingBase, чтобы получить привязку для каждого свойства.

Функция GetBindingsRecursive :

void GetBindingsRecursive(DependencyObject dObj, List<BindingBase> bindingList)
        {
            bindingList.AddRange(DependencyObjectHelper.GetBindingObjects(dObj));

            int childrenCount = VisualTreeHelper.GetChildrenCount(dObj);
            if (childrenCount > 0)
            {
                for (int i = 0; i < childrenCount; i++)
                { 
                    DependencyObject child = VisualTreeHelper.GetChild(dObj, i);
                    GetBindingsRecursive(child, bindingList);
                }
            }
        }

DependencyObjectHelper класс:

public static class DependencyObjectHelper
    {
        public static List<BindingBase> GetBindingObjects(Object element)
        {
            List<BindingBase> bindings = new List<BindingBase>();
            List<DependencyProperty> dpList = new List<DependencyProperty>();
            dpList.AddRange(GetDependencyProperties(element));
            dpList.AddRange(GetAttachedProperties(element));

            foreach (DependencyProperty dp in dpList)
            {
                BindingBase b = BindingOperations.GetBindingBase(element as DependencyObject, dp);
                if (b != null)
                {
                    bindings.Add(b);
                }
            }

            return bindings;
        }

        public static List<DependencyProperty> GetDependencyProperties(Object element)
        {
            List<DependencyProperty> properties = new List<DependencyProperty>();
            MarkupObject markupObject = MarkupWriter.GetMarkupObjectFor(element);
            if (markupObject != null)
            {
                foreach (MarkupProperty mp in markupObject.Properties)
                {
                    if (mp.DependencyProperty != null)
                    {
                        properties.Add(mp.DependencyProperty);
                    }
                }
            }

            return properties;
        }

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

            return attachedProperties;
        }
    }

Пример использования:

List<BindingBase> bindingList = new List<BindingBase>();
GetBindingsRecursive(this, bindingList);

foreach (BindingBase b in bindingList)
{
     Console.WriteLine(b.ToString());
}
4 голосов
/ 09 июля 2014

Существует лучшее решение в .NET 4.5 и выше:

foreach (BindingExpressionBase be in BindingOperations.GetSourceUpdatingBindings(element))
{
    be.UpdateSource();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...