2011-02-16 3 views
2

Window에 대한 모든 BindingExpression 객체를 가져 오는 방법이 있습니까?Window에 대한 모든 BindingExpression 객체를 가져 오는 방법이 있습니까?

양식을 새로 고치기 위해 발생해야하는 Number PropertyChanged 이벤트가 너무 높고 좋은 옵션이 아닐 때 양식을 새로 고치려고합니다. 폼/창 모든 바인딩을 다시 쿼리 할 수있는 다른 방법으로 생각하고 있어요.

+0

[link] 가능한 복제본 (http://stackoverflow.com/questions/1135012) – eFloh

답변

3

업데이트 모든 속성의 null 또는 String.Empty 바인딩의 매개 변수를 가지고있는 PropertyChangedEventArgsPropertyChanged 제기합니다. 그것을 다른 방법으로 주위를하는

[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 공개 : 그에 대한 코드는 다음입니다. 당신은 이것에서 해결책을 쉽게 추론 할 수 있어야합니다.

관련 문제