V
V
Viktor Titov2019-04-13 08:56:42
WPF
Viktor Titov, 2019-04-13 08:56:42

How to properly specify DataContext in MVVM UserControl?

There is such code in MainWindow.xaml:

<Window.Resources>
    <DataTemplate
        DataType="{x:Type vm:MainMenuVM}">
        <v:MainMenu />
    </DataTemplate>
    <DataTemplate
        DataType="{x:Type vm:DataBaseEditorVM}">
        <v:DataBaseEditor />
    </DataTemplate>
</Window.Resources>
<ContentPresenter Content="{Binding CurrentContentVM}"/>

RootVM.cs:
public class RootVM : ObservableObject
{
    private readonly Dictionary<string, BaseVM> mViewModels = new Dictionary<string, BaseVM>();
    private BaseVM mCurrentContentVM;
    public BaseVM CurrentContentVM
    {
        get => mCurrentContentVM;
        set
        {
            mCurrentContentVM = value;
            OnPropertyChanged("CurrentVM");
        }
    }

    public RootVM()
    {
        mViewModels.Add("MainMenu", new MainMenuVM(this));
        mViewModels.Add("DataBaseEditor", new DataBaseEditorVM(this));
        SetVM("MainMenu");
    }

    public void SetVM(string vmName)
    {
        if (mViewModels.ContainsKey(vmName))
        {
            CurrentContentVM = mViewModels[vmName];
        }
    }
}

I removed StartupUri and create MainWindows with RootVM context in App.cs.
new MainWindow { DataContext = RootVM }.Show();
I have a ViewModel for MainMenu which has a command
public Command OpenDataBaseEditorView
    {
        get => mOpenDataBaseEditorView ??
                   (mOpenDataBaseEditorView = new Command((o) =>
                   {
                       mParentVM.SetVM("DataBaseEditor");
                   }));
        private set { }
    }

Accordingly, I expect that it is enough for me to hang it on the Button
<Button Click="{Binding OpenDataBaseEditorView}">Open</Button>

in MainMenu.xaml, and the context will be taken into account at runtime, because you specified the DataTemplate in MainWindow.xaml. But there is an error at runtime pointing to this line with the button. How to correctly assign DataContext to UserControls in MVVM? How in this situation, when I essentially have only CurrentContentVM in RootVM, let me know about it in all UserControls?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
F
Foggy Finder, 2019-04-13
@goldsphere48

The problem is not with the assignment of the DataContext to the UserControl . To bind a command to a button, use the Command property rather than the Click property :

<Button Command="{Binding OpenDataBaseEditorView}">Open</Button>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question