Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ContentControl to display views in WPF doesn't work

I am currently working on a small project by myself to learn WPF better, and a question I was asking myself is how would navigation between different views work if I want to follow the MVVM pattern.

I have stumbled upon this question here answering my question, but unfortunately it does not seem to work. Instead of having my view display, it is only the namespace of the associated viewmodel that is displayed. So, for exemple, instead of seeing my LoginView, I am seeing a white screen with "JollyFinance.ViewModels.LoginViewModel" written.

Here is my MainWindow.xaml code:

<Window.Resources>
    <!-- Different pages -->
     <DataTemplate x:Key="LoginView" DataType="vm:LoginViewModel">
        <views:LoginView />
    </DataTemplate>
</Window.Resources>

<Window.DataContext>
    <vm:MainViewModel/>
</Window.DataContext>

<Grid>
    <ContentControl Content="{Binding CurrentViewModel}"/>
</Grid>

Here is my MainViewModel.cs:

public class MainViewModel : BindableObject
{
    private ViewModelNavigationBase _currentViewModel;

    public MainViewModel()
    {
        CurrentViewModel = new LoginViewModel();
    }

    public ViewModelNavigationBase CurrentViewModel
    {
        get { return _currentViewModel; }
        set
        {
            if (_currentViewModel != value)
            {
                _currentViewModel = value;
                RaisePropertyChanged();
            }
        }
    }
}

My LoginViewModel.cs file:

    public LoginViewModel()
    {
        LoginCommand = new RelayCommand(Login);
        NavigateCommand = new RelayCommand(Login);
    }

    private void Login(object param)
    {
        Popup codePopup = new Popup();
        TextBlock popupText = new TextBlock();
        popupText.Text = "Test";
        popupText.Background = Brushes.LightBlue;
        popupText.Foreground = Brushes.Blue;
        codePopup.Child = popupText;
    }

    public String Username { get; set; }

    public String Password { get; set; }

    public ICommand LoginCommand { get; set; }
}

My LoginView.xaml file is a UserControl comprised of a few Buttons and TextBlocks. BindableObject is just an abstract class that I use that implements the INotifyProperty interface. And ViewModelNavigationBase is the class that all my viewmodels will inherit from; it doesn't contain anything for the moment.

How would I resolve this issue for it to display my view instead of a string representation of the associated viewmodel?

like image 521
Choub890 Avatar asked Nov 30 '22 00:11

Choub890


2 Answers

WPF does not support implicit DataTemplates with string as the type identifier.

You need to use the x:Type Markup Extension to specify your view model type:

<DataTemplate DataType="{x:Type vm:LoginViewModel}">
    <views:LoginView />
</DataTemplate>
like image 109
nemesv Avatar answered Dec 08 '22 00:12

nemesv


I have finally found what the problem was. For some reason, when you declare x:Key on the DataTemplate, it made the ContentControl Content appear as a string. I have removed the x:Key of the DataTemplate and everything works now. I also had to apply nemesv's answer for it to work.

Before:

<DataTemplate x:Key="LoginView" DataType="vm:LoginViewModel">

After (resolves the problem):

<DataTemplate DataType="{x:Type vm:LoginViewModel}">
like image 27
Choub890 Avatar answered Dec 08 '22 00:12

Choub890