2011-02-16 183 views
2

有没有办法让一个窗口的所有BindingExpression对象?有没有办法让一个窗口的所有BindingExpression对象?

我想要刷新窗体时,需要触发刷新窗体的数量PropertyChanged事件太高,不是一个好的选择。我想这样做,窗体/窗口可以重新查询所有绑定的另一种方式。

+0

[link]的可能重复(http://stackoverflow.com/questions/1135012) – eFloh 2011-05-27 10:49:44

回答

3

如果您将PropertyChangedPropertyChangedEventArgs的参数设置为nullString.Empty,则所有属性的绑定都会更新。

[MSDN Reference]

做它周围的其他方法是很多更复杂,可能更耗费的性能,我认为。您需要检查整个窗口中每个DependencyObject的每个DependencyProperty的绑定。

编辑:写了做你问以下粗略的扩展方法,这是非常低效的(有可能是改进的余地,但你仍然处理相当复杂的算法):

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

仅供参考,当您调用BindingOperations.ClearAllBindings()时,WPF本身就会完成此操作(遍历所有数据绑定属性)。 操作的代码如下:

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是公开的,所以你可以使用它。 您应该能够轻松地从中推导出解决方案。

相关问题