Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ContentControl not updating

I'm trying to have a MainWindow that is bound to the a view. I change that view in code and expect it to update in the Main Window, however that is not happening.

I have this code in my XAML

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

I then change my Control via 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'm using the ReactiveUI library.

Is ContentControl the wrong thing to use in that view or am I just not binding and updating correctly?

like image 513
Rumel Avatar asked Mar 12 '13 04:03

Rumel


2 Answers

There is actually a far better way to do this, using ViewModelViewHost:

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

Now, your class will look something like:

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 app's startup, you should write:

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

What's ViewModelViewHost?

ViewModelViewHost will take a ViewModel object that you provide via Bindings, and look up a View that fits it, using Service Location. The Register call is how you can associate Views with ViewModels.

like image 192
Ana Betts Avatar answered Sep 20 '22 13:09

Ana Betts


why you call your class MainWindowViewModel? when you wanna do mvvm you shouldn't have properties with type UserControl in your VM.

the usual mvvm way looks like this:

  • viewmodel with INotifyPropertyChanged
public class MyViewmodel
{
    public IWorkspace MyContent {get;set;}
}
  • xaml content control with binding to your VM
<ContentControl Content="{Binding MyContent}"/>
  • datatemplate --> so that wpf knows how to render your IWorkspace
<DataTemplate DataType="{x:Type local:MyIWorkSpaceImplementationType}" >
   <view:MyWorkspaceView />
</DataTemplate>
like image 38
blindmeis Avatar answered Sep 22 '22 13:09

blindmeis