Bhuvan
Bhuvan

Reputation: 1573

Is there a way to get all BindingExpression objects for a Window?

Is there a way to get all BindingExpression objects for a Window?

I am trying to refresh the form when the number PropertyChanged events that need to be fired to refresh a form is too high and not a good option. I am thinking doing it the other way that the form/window can re-query all bindings.

Upvotes: 2

Views: 2976

Answers (2)

canahari
canahari

Reputation: 522

Just for reference, WPF itself does exactly this (iterates through all the data bound properties) when you call BindingOperations.ClearAllBindings(). The code for that is the following:

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 is public so you can use it too. You should be able to deduce the solution from this easily.

Upvotes: 3

brunnerh
brunnerh

Reputation: 184622

If you raise PropertyChanged with the PropertyChangedEventArgs that have a parameter of null or String.Empty the bindings of all properties will update.

[MSDN Reference]

Doing it the other way around is a lot more complicated and probably more performance consuming i think. You would need to check every DependencyProperty of every DependencyObject in the whole window for bindings.

Edit: Wrote the following sketchy extension method which does what you asked for, it's awfully inefficient (there is probably room for improvement but you're still dealing with an algorithm of considerable complexity):

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

Upvotes: 3

Related Questions