WPF ViewModel与多个View绑定后如何解决的问题

Posted lonelyxmas

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF ViewModel与多个View绑定后如何解决的问题相关的知识,希望对你有一定的参考价值。

原文: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();

 


以上是关于WPF ViewModel与多个View绑定后如何解决的问题的主要内容,如果未能解决你的问题,请参考以下文章

从 View 到 ViewModel 的 WPF 事件绑定?

ViewModel 中的 INotifyPropertyChanged 与 DependencyProperty

WPF MVVM:命令很简单。如何使用 RoutedEvent 连接 View 和 ViewModel

如何使用 Knockout.js 将多个 View 绑定到单个 ViewModel

WPF使用MVVM设计模式 问题

WPF 解决View属性不能注销的问题