Reputation: 1573
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
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
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.
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