I bind a MainWindowViewModel to the DataContext of a MainWindow. Then I initialize this MainWindowViewModel to a specific itemsPageViewModel.
The problem is that on startUp I see itemsPageViewModel 's class name instead of its content:
However, after switching pages through buttons (RelayCommands), the same ViewModel now shows its content:
Both operations pass through the same code-line:
CurrentPageViewModel = _itemsPageViewModel
How can it produce different results?
CODE
MainWindow.xaml
<Window x:Class="ListItemUI.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="ListItemUI" Height="400" Width="600">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal">
<Button Content="ITEMS" Margin="2" Command ="{Binding SelectItemsPageViewModel}"></Button>
<Button Content="HELP" Margin="2" Command ="{Binding SelectInfoPageViewModel}"></Button>
</StackPanel>
</Grid>
<ContentControl Grid.Row="2" Content="{Binding CurrentPageViewModel}"/>
</Grid>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
using ListItemUI.InfoPage.ViewModels;
using ListItemUI.ListItemPage.ViewModels;
using ListItemUI.ViewModels;
namespace ListItemUI.Views
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow(IPageFactory itemPageFactory, IPageFactory infoPageFactory)
{
InitializeComponent();
var mainWindowVM = new MainWindowViewModel(itemPageFactory,infoPageFactory);
DataContext = mainWindowVM;
}
}
}
MainWindowViewModel.cs
using System;
using System.Windows.Input;
using ListItemUI.ListItemPage.ViewModels;
namespace ListItemUI.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
private readonly IListItemUIViewModel _itemsPageViewModel;
private readonly IListItemUIViewModel _infoPageViewModel;
public ICommand SelectItemsPageViewModel { get; }
public ICommand SelectInfoPageViewModel { get; }
public object CurrentPageViewModel
{
get { return _currentPageViewModel; }
set
{
_currentPageViewModel = value;
RaisePropertyChanged(() => CurrentPageViewModel);
}
}
private object _currentPageViewModel;
public MainWindowViewModel(IPageFactory itemsPageFactory, IPageFactory infoPageFactory)
{
_itemsPageViewModel = itemsPageFactory.CreatePage();
_infoPageViewModel = infoPageFactory.CreatePage();
SelectItemsPageViewModel = new RelayCommand(_ =>
{
CurrentPageViewModel = _itemsPageViewModel;
});
SelectInfoPageViewModel = new RelayCommand(_ =>
{
CurrentPageViewModel = _infoPageViewModel;
});
CurrentPageViewModel = _itemsPageViewModel;
}
}
}
ListItemPage.xaml (dataTemplates)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels ="clr-namespace:ListItemUI.ListItemPage.ViewModels">
<DataTemplate DataType="{x:Type viewModels:ItemViewModel}">
<StackPanel>
<TextBlock Foreground="RoyalBlue" FontWeight="Bold" Text="{Binding Path=ItemViewDescription, StringFormat='Group Info = {0}'}"></TextBlock>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:ItemsPageViewModel}">
<StackPanel>
<TextBlock Text ="{Binding Path=Title}"></TextBlock>
<Grid Grid.Column="0" Background="Aquamarine">
<ListBox ItemsSource="{Binding Path=LocalItemViewModels}" Margin="5">
</ListBox>
</Grid>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
App.xaml
<Application x:Class="ListItemUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ListItemPage/Views/ListItemPage.xaml"></ResourceDictionary>
<ResourceDictionary Source="InfoPage/Views/InfoView.xaml"></ResourceDictionary>
<!--GLOBAL RESOURCES -->
<ResourceDictionary Source="Views/GlobalResources.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
We used a workaround to solve this specific problem. We chose not to use resource dictionaries, putting the dataTemplates of the viewModels directly into the mainwindow.xaml: now everything works. Something strange happens when we use resource dictionaries.