简体   繁体   中英

WPF using MVVM Light: How to bind a ContentControl to a child property

I am trying to implement an intermediary class ViewModelSelector that sets up and selects the current View/ViewModel to be shown as part of the main view main window MainView.xaml . I am trying to do this by defining a DataTemplate for ViewModel1 (see below) inside MainView.xaml and then using a ContentControl which I bind to the property CurrentViewModel of ViewModelSelector . The ViewModelSelector assigns ViewModel1 to its property CurrentViewModel . The idea is then to extend this with more DataTemplates and ViewModels and using UserControls to have the ViewModelSelector setup and decide which ViewModel to show ( ViewModel1 , ViewModel2 , etc.). However for some reason this is not working:

When binding the ContentControl to ViewModelSelector.CurrentViewModel using <ContentControl Content="{Binding ViewModelSelector.CurrentViewModel}"/> the datatemplate is not shown (see MainView.xaml below). But no other error is thrown (that I can tell).

For debugging purposes I also created a CurrentViewModelInMainViewModel property in MainViewModel.cs which I set to ViewModelSelector.CurrentViewModel ( CurrentViewModelInMainViewModel = ViewModelSelector.CurrentViewModel; ). Binding directly to it ( <ContentControl Content="{Binding CurrentViewModelInMainViewModel}"/> ) works and the DataTemplate is shown.

So what am I doing wrong?

Here is the elided code. I hope I did not put any error in it, as I am not at work right now and can't test ...

My MainViewModel.cs :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProgramEditor.ViewModel
{
    using GalaSoft.MvvmLight;
    using ProgramEditor.View;

    class MainWindowViewModel : ViewModelBase
    {
    private ViewModelSelector ViewModelSelector;
    public ViewModelSelector ViewModelSelector
    {
        get { return ViewModelSelector; }
        set {
            ViewModelSelector = value;
            RaisePropertyChanged("ViewModelSelector");
        }
    }

    private ViewModelBase currentViewModelInMainViewModel;
    public ViewModelBase CurrentViewModelInMainViewModel
    {
        get
        {
            return currentViewModelInMainViewModel;
        }
        set
        {
            if (currentViewModel == value)
                return;
            currentViewModelInMainViewModel = value;
            RaisePropertyChanged("CurrentViewModelInMainViewModel");
        }
    }

    public MainWindowViewModel()
    {
        ViewModelSelector ViewModelSelector = new ViewModelSelector();
        CurrentViewModelInMainViewModel = ViewModelSelector.CurrentViewModel;
    }
    }
}

The class ViewModelSelector :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProgramEditor.ViewModel
{
    using GalaSoft.MvvmLight;

    class ViewModelSelector : ViewModelBase
    {
    public ViewModelBase CurrentViewModel
    {
        get { return currentViewModel; }
        set
        {
        if (currentViewModel == value)
            return;
        currentViewModel = value;
        RaisePropertyChanged("CurrentViewModel");
        }
    }
    private ViewModelBase currentViewModel;

    public ViewModelSelector()
    {
        CurrentViewModel = new ViewModel1();
    }
    }
}

The dummy ViewModel1 :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProgramEditor.ViewModel
{
    using GalaSoft.MvvmLight;

    public class ViewModel1 : ViewModelBase
    {
    }
}



    <DataTemplate DataType="{x:Type ViewModel:FirstViewModel}">
        <TextBlock Text="There be dragons here." FontSize="50"/>
    </DataTemplate>

My MainView.xaml :

<Window x:Class="ProgramEditor.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:view="clr-namespace:ProgramEditor.View"
    xmlns:ViewModel="clr-namespace:ProgramEditor.ViewModel"
    Title="MainWindow" Height="900" Width="1600">

    <Window.Resources>
        <DataTemplate DataType="{x:Type ViewModel:ViewModel1}">
            <TextBlock Text="There be dragons here." FontSize="50"/>
        </DataTemplate>
    </Window.Resources>

    <StackPanel>
        <!-- This works (shows up in main window): -->
        <ContentControl Content="{Binding CurrentViewModelInMainViewModel}"/>
        <!-- This does not work (does not show up in main window): -->
        <!--<ContentControl Content="{Binding ViewModelSelector.CurrentViewModel}"/>-->
    </StackPanel>
</Window>

The answer was a trivial programming error. I was overriding the ViewModelSelector property in the constructor of MainViewModel.cs here: ViewModelSelector ViewModelSelector = new ViewModelSelector();

After changing that line to ViewModelSelector = new ViewModelSelector(); it now works as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM