原文: WPF ViewModel與多個View綁定後如何解決的問題
當重複建立View并綁定同一個ViewModel後,ViewModel中的字段更新,在新的View中的沒有反應或者在View中找不到相應的視覺樹(如ListBox的ListBoxItem)
初始的解決方案:View關閉後,登出屬性Unregister Dependency。
如果可以将屬性登出,貌似是可行的
登出屬性 RemoveDependency(LoadCousewareItemAnimationProperty);
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();