Есть ли способ получить все объекты BindingExpression для окна? - PullRequest
2 голосов
/ 17 февраля 2011

Есть ли способ получить все объекты BindingExpression для окна?

Я пытаюсь обновить форму, когда число событий PropertyChanged, которые необходимо запустить для обновления формы, слишком велико и не является хорошим вариантом.Я думаю сделать это другим способом, чтобы форма / окно могли повторно запросить все привязки.

Ответы [ 2 ]

3 голосов
/ 09 июля 2014

Просто для справки, сам WPF делает именно это (перебирает все свойства привязки данных), когда вы вызываете BindingOperations.ClearAllBindings ().Код для этого следующий:

public static void ClearAllBindings(DependencyObject target)
{
    if (target == null)
    {
        throw new ArgumentNullException("target");
    }
    LocalValueEnumerator localValueEnumerator = target.GetLocalValueEnumerator();
    ArrayList arrayList = new ArrayList(8);
    while (localValueEnumerator.MoveNext())
    {
        LocalValueEntry current = localValueEnumerator.Current;
        if (BindingOperations.IsDataBound(target, current.Property))
        {
            arrayList.Add(current.Property);
        }
    }
    for (int i = 0; i < arrayList.Count; i++)
    {
        target.ClearValue((DependencyProperty)arrayList[i]);
    }
}

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

3 голосов
/ 17 февраля 2011

Если вы повысите PropertyChanged с PropertyChangedEventArgs, который имеет параметр null или String.Empty, привязки всех свойств обновятся.

[ MSDN Reference ]

Сделать это наоборот намного сложнее и, вероятно, потреблять больше производительности, я думаю. Вам нужно будет проверить каждый DependencyProperty каждого DependencyObject во всем окне на наличие привязок.

Редактировать: Написал следующий схематичный метод расширения, который делает то, что вы просили, он ужасно неэффективен (возможно, есть возможности для улучшения, но вы все еще работаете с алгоритмом значительной сложности):

public static void UpdateAllBindings(this DependencyObject o)
{
    //Immediate Properties
    List<FieldInfo> propertiesAll = new List<FieldInfo>();
    Type currentLevel = o.GetType();
    while (currentLevel != typeof(object))
    {
        propertiesAll.AddRange(currentLevel.GetFields());
        currentLevel = currentLevel.BaseType;
    }
    var propertiesDp = propertiesAll.Where(x => x.FieldType == typeof(DependencyProperty));
    foreach (var property in propertiesDp)
    {
        BindingExpression ex = BindingOperations.GetBindingExpression(o, property.GetValue(o) as DependencyProperty);
        if (ex != null)
        {
            ex.UpdateTarget();
        }
    }

    //Children
    int childrenCount = VisualTreeHelper.GetChildrenCount(o);
    for (int i = 0; i < childrenCount; i++)
    {
        var child = VisualTreeHelper.GetChild(o, i);
        child.UpdateAllBindings();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...