天天看點

WPF ViewModel與多個View綁定後如何解決的問題

原文: WPF ViewModel與多個View綁定後如何解決的問題

當重複建立View并綁定同一個ViewModel後,ViewModel中的字段更新,在新的View中的沒有反應或者在View中找不到相應的視覺樹(如ListBox的ListBoxItem)

初始的解決方案:View關閉後,登出屬性Unregister Dependency。

如果可以将屬性登出,貌似是可行的

登出屬性 RemoveDependency(LoadCousewareItemAnimationProperty);

WPF ViewModel與多個View綁定後如何解決的問題
WPF ViewModel與多個View綁定後如何解決的問題

1 private void RemoveDependency(DependencyProperty prop)
 2 {
 3   var registeredPropertyField = typeof(DependencyProperty).
 4     GetField("RegisteredPropertyList", BindingFlags.NonPublic | BindingFlags.Static);
 5   object list = registeredPropertyField.GetValue(null);
 6   var genericMeth = list.GetType().GetMethod("Remove");
 7   try
 8   {
 9     genericMeth.Invoke(list, new[] { prop });
10   }
11   catch (TargetInvocationException)
12   {
13     Console.WriteLine("Does not exist in list");
14   }
15 
16   var propertyFromNameField = typeof(DependencyProperty).
17     GetField("PropertyFromName", BindingFlags.NonPublic | BindingFlags.Static);
18   var propertyFromName = (Hashtable)propertyFromNameField.GetValue(null);
19 
20   object keyToRemove = null;
21   foreach (DictionaryEntry item in propertyFromName)
22   {
23     if (item.Value == prop){        
24        keyToRemove = item.Key;
25        return;
26     }
27   }
28   if (keyToRemove != null)
29   propertyFromName.Remove(keyToRemove);
30 }      

View Code

運作了下,登出成功!

但是,随之來的新問題是,因舊View的DataContext依舊綁定着ViewModel,屬性登出了,但是ViewModel的字段更新時,會找不到View的屬性,直接抛出異常!

正确簡潔的處理方案:UnLoaded事件中,設定DataContext = null

字段更新,不會通知到舊View。

值得注意的是,在View的依賴屬性中,如屬性添加了PropertyChanged事件,一定要将e.NewValue判空。

因屬性之前綁定了資料,DataContext = null為空之後,會觸發PropertyChanged。

Loaded += (s, e) =>
    {
        if (DataContext == null)
        {
            DataContext = _viewModel;
        }
    };
    Unloaded += (s, e) =>
    {
        this.DataContext = null;
    };
    _viewModel=new ViewModel();