WPF,MVVM和ComboBox:当更改为不同的viewmodel时,ComboBox使绑定到SelectedItem的属性为空

时间:2011-03-16 23:48:15

标签: wpf mvvm combobox

我有一个Window,它使用DataTemplates在ContentPresenter中根据其Content属性的类型显示不同的UserControl(视图),该属性绑定到包含当前viewmodel的属性。通过这种方式,通过使用事件更改viewmodel属性,我可以方便我需要的基本后退/前进导航。

创建新的viewmodel时,会传递对当前视图模型的引用。回到旧的viewmodel实例适用于CheckBox控件,但不适用于我制作的包含TextBlock和ComboBox的UserControl。

问题在于,当包含ComboBox的视图被卸载时,ComboBox的ItemsSource被取消,这会触发它清除其SelectedItem / Text属性,这些属性由于某种原因仍然绑定到我的viewmodel - 从而清除数据它存储。我不知道如何在适当的时候手动取消绑定它们。 (再次,CheckBox工作正常。)

我已经读过其他用户遇到了同样的问题。对于它们,更改ItemsSource和SelectedItem / Text绑定的声明顺序,以便后者的属性放在前者之前修复问题。但是,在我的情况下,它没有。其他人也通过忽略null / empty值来解决这个问题,但这在我的情况下不起作用。

我可以通过将有趣的数据复制到一个单独的对象并从中重新加载来解决这个问题,但是我需要添加代码来触发重新加载数据=更多的数据链接代码来维护。

我还可以避免使用DataTemplates并在代码隐藏中手动添加UserControls,这样我就可以在删除UserControl之前中断数据绑定。但这与MVVM的观点背道而驰。

我不是要修改我的非MVVM UserControl来处理它包含的ComboBox上的任何事件来解决这个问题。


更新

我已经稍微缩小了这个问题。我重构了代码,以便它根据已设置的viewmodel手动创建并添加视图UserControl。现在只有在我将视图UserControl的DataContext设置为null时才会出现此问题。如果我只是在不删除引用的情况下替换视图,则不再删除有问题的值。这是一个可用的解决方法,还是会产生内存泄漏等问题?

3 个答案:

答案 0 :(得分:0)

这是由事件跳跃引起的WPF早期版本中的已知错误。它已针对.NET 4.0中的Selector派生控件进行了修复。

有关详细信息,请参阅此博客文章:http://blogs.interknowlogy.com/2011/03/09/event-leapfrogging/

答案 1 :(得分:0)

我通过在我的基本viewmodel类中添加一个属性Active和相应的Activate()/ Deactivate()方法来解决这个问题,并在交换viewmodel时适当地调用它们。这非常适合我的应用程序。当然,我仍然愿意接受其他建议。

答案 2 :(得分:0)

对于更简单的解决方案,可能会“开放思想”......如果我理解你的问题,那就类似于我们过去的问题了。在我们的例子中,我们只是假设在绑定属性访问时不可能将特定值设置为null,因此我们稍微调整了相应的ViewModel属性:

public MyItem SelectedItem {
  get {
    return Model.MyItem;
  }
  set {
     if (value != null) {
       // Set and notify if not null
       Model.MyItem = value;
       OnPropertyChanged("SelectedItem");
     }
     else // just notify when trying to set to null
       OnPropertyChanged("SelectedItem");
  }
}

使用这样的调整属性,我们可以阻止任何尝试将值设置为null,通过调用OnPropertyChanged(..) insead,UI会调用现有值。如果需要能够将值设置为null,则必须提供允许该值的单独属性。

不确定这是否适用于您的问题。 祝你好运。

<强>更新
哦,我看到可能这描述了相同的方法,“其他人也通过忽略空值/空值来修复问题”,这似乎不适用于您的情况。但我不解释为什么不应该这样做。