2

I am working on a WPF app using the MVVM pattern. However , I am facing troubles with it, since it's the first time I try to use the MVVM pattern.

I have a main window view, and 2 UserControls, that I want to switch using Buttons. Easy as it is, I am stuck with the the following code, which should work but nothing happen when I click on the button:

MainView.xaml

<Window x:Class="WindowsClient.View.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:WindowsClient.ViewModel"
    xmlns:local="clr-namespace:WindowsClient.View"
    Height="768" Width="1366" MinHeight="768" MinWidth="1366">
<Window.Resources>
    <DataTemplate DataType="{x:Type vm:HomeViewModel}">
        <local:HomeView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:ProfilViewModel}">
        <local:ProfilView/>
    </DataTemplate>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="240"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <!-- LeftMenu -->
    <Border Grid.Column="0" Background="Black">
        <StackPanel>
            <Button Content="Home" Command="{Binding HomeViewCommand}"></Button>
            <Button Content="Profil" Command="{Binding ProfilViewCommand}"></Button>
        </StackPanel>
    </Border>
    <!-- Body -->
    <ContentControl x:Name="Pages" Content="{Binding ContentControlViewModel}" Grid.Column="1"/>
</Grid>

MainViewModel.cs

namespace WindowsClient.ViewModel
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        private object contentControlViewModel;
        public object ContentControlViewModel
        {
            get => contentControlViewModel;
            set
            {
                contentControlViewModel = value;
                OnPropertyChanged("ContentControlViewModel");
            }
        }

        public MainWindowViewModel()
        {
            HomeViewCommand = new BaseCommand(OpenHome);
            ProfilViewCommand = new BaseCommand(OpenProfil);

        }
        public ICommand HomeViewCommand { get; set; }

        public ICommand ProfilViewCommand { get; set; }

        public void OpenHome(object obj)
        {
            ContentControlViewModel = new HomeViewModel();
        }

        public void OpenProfil(object obj)
        {
            ContentControlViewModel = new ProfilViewModel();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    }

    public class BaseCommand : ICommand
    {
        private Predicate<object> _canExecute;
        private Action<object> _method;
        public event EventHandler CanExecuteChanged;

        public BaseCommand(Action<object> method)
            : this(method, null)
        {
        }

        public BaseCommand(Action<object> method, Predicate<object> canExecute)
        {
            _method = method;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }

            return _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _method.Invoke(parameter);
        }
    }
}

HomeView.xaml

<UserControl x:Class="WindowsClient.View.HomeView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Height="768" Width="1126"
             MinHeight="768" MinWidth="1126">
    <Grid>
        <ToggleButton x:Name="CommunityButton" Content="Community" Height="30" Width="200" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="-300,100,0,0" FontSize="18" />
        <ToggleButton x:Name="NewsButton" Content="News" Height="30" Width="200" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="300,100,0,0" FontSize="18"/>
        <ScrollViewer x:Name="HomeContentViewer" Margin="10,150,10,10"/>
    </Grid>
</UserControl>

HomeViewModel.cs

namespace WindowsClient.ViewModel
{
    internal class HomeViewModel
    {

    }
}

ProfilView and ProfilViewModel are pretty much the same as those two.

Anyway, when I click on a button, the view does not change and I can't understand why...

2
  • 3
    I assume you're clicking the "Home" or "Profil" button, right? Have you tried setting a breakpoint in OpenHome or OpenProfil to see if your command is executing? Is the DataContext on your MainView actually being set to a MainWindowViewModel instance? Commented Feb 20, 2018 at 19:11
  • Yes exactly. I tried the breakpoint in OpenHome/OpenProfil but it seems that it never reaches it. I am going to look arround for the DataContext, maybe I missed something about it. Commented Feb 20, 2018 at 19:34

1 Answer 1

3

This bit is missing from your MainView.xaml:

<Window.DataContext>
    <local:MainWindowViewModel/>
</Window.DataContext>

You can add that just above your <Window.Resources> line.

That would be why nothing is being bound to your view from your viewmodel.

Sign up to request clarification or add additional context in comments.

1 Comment

That was the problem. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.