Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding ViewModel to ContentControl as its DataContext

Tags:

c#

mvvm

wpf

I want to change UserControls on button clicks (I'm not going to complicate here, so I'll only mention important parts). So idea was to bind ViewModels of those UserControls to ContentControl, and than associate them Views using DataTemplates. Here's the code:

<Window x:Class="Project.MainWindow">
<Window.Resources>
    <DataTemplate DataType="{x:Type UserControl:ViewUserControlViewModel}" >
        <UserControl:ViewUserControl/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type UserControl:EditUserControlViewModel}" >
        <UserControl:EditUserControl/>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ContentControl DataContext="{Binding UserControlViewModel}" />
    <Button Content="View" Click="ChangeToView()"/>
    <Button Content="Edit" Click="ChangeToEdit()"/>
</Grid>
</Window>

ViewModel:

public class MainWindowViewModel : DependencyObject
{
    public DependencyObject UserControlViewModel
    {
        get { return (DependencyObject)GetValue(UserControlViewModelProperty); }
        set { SetValue(UserControlViewModelProperty, value); }
    }
    public static readonly DependencyProperty UserControlViewModelProperty = 
           DependencyProperty.Register("UserControlViewModel", typeof(DependencyObject), typeof(MainWindowViewModel), new PropertyMetadata());

    public MainWindowViewModel()
    {
        UserControlViewModel = new EditUserControlViewModel();
    }
}

But theres a problem. When I start project, I only see buttons but not any UserControls. What did I do wrong?

like image 362
Miro Avatar asked Jul 19 '12 23:07

Miro


2 Answers

If your Window.DataContext is properly set to MainWindowViewModel this should do the job

<ContentControl Content="{Binding UserControlViewModel}" />
like image 173
LPL Avatar answered Sep 22 '22 12:09

LPL


When doing mvvm your viewmodel should implement INotifyPropertyChanged and not inherit from DependencyObject.

public class MainWindowViewModel : INotifyPropertyChanged
{
   private object _currentWorkspace; //instead of object type you can use a base class or interface
   public object CurrentWorkspace
   {
      get { return this._currentWorkspace; }
      set { this._currentWorkspace = value; OnPropertyChanged("CurrentWorkspace"); }
   }


   public MainWindowViewModel()
   {
      CurrentWorkspace= new EditUserControlViewModel();
   }

   //todo: to switch the workspace, create DelegeCommand/RelayCommand and set the CurrentWorkspace
   //if you don't know about these commands let me know and i post it

   public ICommand SwitchToViewCommand {get{...}}
   public ICommand SwitchToEditCommand {get{...}}
}

xaml: you should set the Content Property to your CurrentWorkspace.

<ContentPresenter Content="{Binding UserControlViewModel}" />
<Button Content="View" Comamnd="{Binding SwitchToViewCommand}"/>
<Button Content="Edit" Comamnd="{Binding SwitchToEditCommand}"/>

! Don't forget to set the DataContext for your window to your MainWindowViewModel instance.

like image 24
blindmeis Avatar answered Sep 20 '22 12:09

blindmeis