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?
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>
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}">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With