开发者

WPF, MVVM, and ComboBox: when changing to a different viewmodel, the ComboBox nulls the property bound to SelectedItem

I have a Window that uses DataTemplates to display a different UserControl (view) in a ContentPresenter based on the type of its Content property, which is bound to a property that holds the current viewmodel. In this way, by changing the viewmodel property with an event, I can facilitate the basic back/forward navigation I need.

When creating a new viewmodel, it is passed a reference to the current one. Going back to the old viewmodel instance works fine for a CheckBox control, but not for a UserControl I made that contains a TextBlock and a ComboBox.

The problem is that, when the view containing the ComboBox gets unloaded, the ComboBox's ItemsSource gets nulled, which triggers it to clear its SelectedItem/Text properties, which are for some reason still bound to my viewmodel--thus clearing the data it stores. I don't know how to manually unbind them at the appropriate time. (Again, the CheckBox works just fine.)

I have read that other users have had this exact same problem. For them, changing the declaration order of the ItemsSource and SelectedItem/Text bindings so that the attributes for the latter are placed before the former fixes the issue. However, in my case, it does not. Others have also fixed the issue by ignoring null/empty values, but this won't work in my case.

I could work around the issue by copying the interesting data to a separate object, and reloading it from that, but I would need to add code to trigger reloading the data = more data linkage code to maintain.

I could also avoid using DataTemplates and manually add the UserControls in the codebehind, which would allow me to break the data binding before removing t开发者_开发技巧he UserControl. But this runs counter to the point of MVVM.

I'm not above modifying my very non-MVVM UserControl to handle any events on the ComboBox it contains to work around this issue.


UPDATE:

I have narrowed down the issue a little bit. I refactored the code so that it manually creates and adds the view UserControl based on which viewmodel has been set. The issue now only occurs when I set the DataContext of the view UserControl to null. If I simply replace the view without removing the reference, it no longer erases the values in question. Is this a usable workaround, or does it create issues like memory leaks?


Maybe something that would "open mind" for a simpler solution... If I understand your problem, it's similar to a past problem we had. In our case, we simply made the assumption that it's not possible to set a specific value to null when accessed by the bound property, so we tweaked the appropriate ViewModel Properties a bit:

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");
  }
}

Using such tweaked properties we were able to block any try to set the value to null, by calling OnPropertyChanged(..) insead, the existing value was recalled by the UI. If there is a need to be able to set a value to null, you have to provide a seperate property allowing that.

Not sure if this applies to your problem. Good luck.

UPDATE
oh, I see probably this describes same method as "Others have also fixed the issue by ignoring null/empty values" which seems not to work in your case. But I dont unterstand why it shouldn't.


This is a known bug in the early versions of WPF caused by event leapfrogging. It was fixed for the Selector-derived controls in .NET 4.0.

See this blog post for more details: http://blogs.interknowlogy.com/2011/03/09/event-leapfrogging/


I have worked around the issue by adding a property Active and corresponding Activate()/Deactivate() methods to my base viewmodel class, and calling these as appropriate when swapping out viewmodels. This fits into my application pretty well. I'm still open to other suggestions, of course.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜