ContentControl does not update

I am trying to have a MainWindow attached to a view. I change this view in the code and expect it to be updated in the main window, but this does not happen.

I have this code in my XAML

<Grid> <ContentControl Content="{Binding Source={StaticResource ViewModelLocator}, Path=MainWindowViewModel.CurrentControl}" /> </Grid> 

Then I change my control with this code

 public class MainWindowViewModel : ReactiveObject { private UserControl _CurrentControl = null; public UserControl CurrentControl { get { if (_CurrentControl == null) { _CurrentControl = new HomePage(); } return _CurrentControl; } set { this.RaiseAndSetIfChanged(x => x.CurrentControl, value); } } } 

As you can see, I am using the ReactiveUI library.

Is ContentControl wrong thing to use in this view, or am I just not getting attached and not updating correctly?

+4
source share
3 answers

In fact, there is a much better way to do this using ViewModelViewHost :

 <Grid DataContext="{Binding ViewModel, ElementName=TheUserControl}"> <ViewModelViewHost ViewModel="{Binding CurrentControlViewModel}" /> </Grid> 

Your class will now look something like this:

 public class MainWindowViewModel : ReactiveObject { private ReactiveObject _CurrentControlViewModel = new HomePageViewModel(); public ReactiveObject CurrentControlViewModel { get { return _CurrentControl; } set { this.RaiseAndSetIfChanged(x => x.CurrentControlViewModel, value); } } } 

And somewhere in your application run, you should write:

 RxApp.Register(typeof(IViewFor<HomePageViewModel>), typeof(HomePage)); 

What is ViewModelViewHost?

ViewModelViewHost will take the ViewModel object that you provide through Bindings and find the view that suits it using Service Location. The Register call is how you can associate Views with ViewModels.

+6
source

why are you calling your MainWindowViewModel class? when you want to do mvvm, you should not have properties with type UserControl in your virtual machine.

The usual mvvm way looks like this:

  • viewmodel with INotifyPropertyChanged
 public class MyViewmodel { public IWorkspace MyContent {get;set;} } 
  • xaml content control bound to your virtual machine
 <ContentControl Content="{Binding MyContent}"/> 
  • datatemplate -> so that wpf knows how to make your IWorkspace
 <DataTemplate DataType="{x:Type local:MyIWorkSpaceImplementationType}" > <view:MyWorkspaceView /> </DataTemplate> 
+5
source

I think you have some confusing concepts here, and they fall into each other.

Firstly, you are not actually using ANY of the reactive UI code, it is never called. Since your get accessor implements a lazy instantiation pattern, this means that the set accessory is ignored. This means that the view never notifies you of a property change, so you never receive updates.

I would recommend using something more similar.

 private UserControl _currentControl; public MainWindowVirwModel() { CurrentControl = new HomePage(); } public UserControl CurrentControl { get { return _curentControl;} set { this.RaiseAndSetIfChanged(...); } } 

In addition, it still mixes View i components, i.e. HomePage, inside your ViewModel level, which will greatly simplify device testing.

+3
source

All Articles