WPF View在关闭时将ViewModel属性设置为null

我有一个应用程序,我在GroupBox中显示UserControls。 为了显示控件,我绑定到主窗体的ViewModel中的属性,该属性返回要显示的ViewModel。 我已经设置了DataTemplates,以便表单自动知道用于显示每个ViewModel的UserControl / View。

当我显示不同的UserControl时,我保持前一个控件的ViewModel处于活动状态,但WPF会自动丢弃视图。

我遇到的问题是,当视图关闭时,任何对ViewModel中属性的双向绑定都会立即设置为null,因此当我再次显示ViewModel时,所有值都只是设置为null UI。

我假设这是因为作为View关闭的一部分,它处理并清除它包含的控件中的任何值,并且由于绑定到位,它们也传播到ViewModel。

DataTemplates在我的资源中

         

用于显示用户控件的代码

    

我在其中一个视图中绑定的控件示例:

   

以及相关的ViewModel属性:

 public ObservableCollection Supervisors { get { return supervisors; } } public int? SelectedSupervisorID { get { return selectedSupervisorID; } set { selectedSupervisorID = value; this.OnPropertyChanged("SelectedSupervisorID"); } } 

有关如何停止我的视图的任何想法使我的ViewModel中的值无效? 我想也许我需要在关闭之前将View的DataContext设置为null,但我不确定如何通过当前绑定的方式来解决这个问题。

我找到了一个可能的解决方案,但我真的不喜欢它。

事实certificateDataContext IS已经设置为null,但这没有帮助。 它在属性设置为null之前发生。 似乎正在发生的事情是在UserControl / View处置自身之前没有删除数据绑定,因此当删除控件时,null值会向下传播。

因此,当DataContext更改时,如果新上下文为null,则删除ComboBox上的相关绑定,如下所示:

 private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { if (e.NewValue == null) { SupervisorDropDown.ClearValue(ComboBox.SelectedValueProperty); } } 

我不是这种方法的忠实粉丝,因为这意味着我必须记住为我使用的每个数据绑定控件做这件事。 如果有一种方法我可以让每个UserControl只是在它们关闭时自动删除它们的绑定就可以了,但我想不出有任何办法可以做到这一点。

另一种选择可能是重新构建我的应用程序,以便在ViewModel执行之前不会销毁视图 – 这将完全回避问题。

当我显示不同的UserControl时,我保持前一个控件的ViewModel处于活动状态,但WPF会自动丢弃视图。

我遇到的问题是,当视图关闭时,任何对ViewModel中属性的双向绑定都会立即设置为null,因此当我再次显示ViewModel时,所有值都只是设置为null UI。

我不是WPF或MVVM的专家,但有些事情听起来不对。 我很难相信WPF处理视图会导致您的问题。 至少,在我有限的经历中,我从未有过这样的事情。 我怀疑罪魁祸首是视图模型中的代码或代码交换出哪个视图模型用于datacontext。

在尝试通过各种方式停止空设置后,我放弃了,而是让它按如下方式工作。 在关闭视图之前,我将ViewModel设置为只读。 我在我的ViewModelBase类中实现了这一点,我在其中添加了一个IsReadOnly布尔属性。 然后在ViewModelBase.SetProperty()(见下文)中,当IsReadOnly为true时,我忽略任何属性更改。

  protected bool SetProperty( ref T backingField, T value, string propertyName ) { var change = !IsReadOnly && !EqualityComparer.Default.Equals( backingField, value ); if ( change ) { backingField = value; OnPropertyChanged( propertyName ); } return change; } 

这似乎是这样的,虽然我仍然想知道更好的解决方案。

我有同样的问题。 对我有用的是从SelectedValueBindings中删除UpdateSourceTrigger = PropertyChanged 。 使用该模式时,PropertyChanged UpdateSourceTriggers似乎触发关闭视图的绑定属性:

                               

容器视图:

                            

容器ViewModel:

 TabCollection.Add(new WelcomeTabViewModel()); TabCollection.Add(new UserSecurityViewModel(_userService, _bpcsUsersLookup)); TabCollection.Add(new PackItemRegisterViewModel(_packItemService, _itemClassLookup)); SelectedTabIndex = 0; 

UpdateSourceTrigger显式设置为LostFocus

如果视图正在关闭并将其数据设置为null,则它对viewmodel中的数据没有影响。