MVVM/WPF: DataTemplate is not changed in Wizard
- by msfanboy
Hello,
I wonder why my contentcontrol(headeredcontentcontrol) does not change the datatemplates when I press the previous/next button. While debugging everything seems ok means I jump forth and back the collection of wizardpages but always the first page is shown and its header text not the usercontrol is visible.
What do I have forgotten?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GalaSoft.MvvmLight.Command;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.ComponentModel;
namespace TBM.ViewModel
{
public class WizardMainViewModel
{
WizardPageViewModelBase _currentPage;
ReadOnlyCollection _pages;
RelayCommand _moveNextCommand;
RelayCommand _movePreviousCommand;
public WizardMainViewModel()
{
this.CurrentPage = this.Pages[0];
}
public RelayCommand MoveNextCommand { get { return _moveNextCommand ?? (_moveNextCommand = new RelayCommand(() => this.MoveToNextPage(), () => this.CanMoveToNextPage)); } }
public RelayCommand MovePreviousCommand { get { return _movePreviousCommand ?? (_movePreviousCommand = new RelayCommand( () => this.MoveToPreviousPage(), () => this.CanMoveToPreviousPage)); } }
bool CanMoveToPreviousPage
{
get { return 0 < this.CurrentPageIndex; }
}
bool CanMoveToNextPage
{
get { return this.CurrentPage != null && this.CurrentPage.IsValid(); }
}
void MoveToPreviousPage()
{
this.CurrentPage = this.Pages[this.CurrentPageIndex - 1];
}
void MoveToNextPage()
{
if (this.CurrentPageIndex < this.Pages.Count - 1)
this.CurrentPage = this.Pages[this.CurrentPageIndex + 1];
}
/// <summary>
/// Returns the page ViewModel that the user is currently viewing.
/// </summary>
public WizardPageViewModelBase CurrentPage
{
get { return _currentPage; }
private set
{
if (value == _currentPage)
return;
if (_currentPage != null)
_currentPage.IsCurrentPage = false;
_currentPage = value;
if (_currentPage != null)
_currentPage.IsCurrentPage = true;
this.OnPropertyChanged("CurrentPage");
this.OnPropertyChanged("IsOnLastPage");
}
}
public bool IsOnLastPage
{
get { return this.CurrentPageIndex == this.Pages.Count - 1; }
}
/// <summary>
/// Returns a read-only collection of all page ViewModels.
/// </summary>
public ReadOnlyCollection<WizardPageViewModelBase> Pages
{
get { return _pages ?? CreatePages(); }
}
ReadOnlyCollection<WizardPageViewModelBase> CreatePages()
{
WizardPageViewModelBase welcomePage = new WizardWelcomePageViewModel();
WizardPageViewModelBase schoolclassPage = new WizardSchoolclassSubjectPageViewModel();
WizardPageViewModelBase lessonPage = new WizardLessonTimesPageViewModel();
WizardPageViewModelBase timetablePage = new WizardTimeTablePageViewModel();
WizardPageViewModelBase finishPage = new WizardFinishPageViewModel();
var pages = new List<WizardPageViewModelBase>();
pages.Add(welcomePage);
pages.Add(schoolclassPage);
pages.Add(lessonPage);
pages.Add(timetablePage);
pages.Add(finishPage);
return _pages = new ReadOnlyCollection<WizardPageViewModelBase>(pages);
}
int CurrentPageIndex
{
get
{
if (this.CurrentPage == null)
{
Debug.Fail("Why is the current page null?");
return -1;
}
return this.Pages.IndexOf(this.CurrentPage);
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
<UserControl x:Class="TBM.View.WizardMainView"
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"
xmlns:ViewModel="clr-namespace:TBM.ViewModel"
xmlns:View="clr-namespace:TBM.View"
mc:Ignorable="d"
>
<UserControl.Resources>
<DataTemplate DataType="{x:Type ViewModel:WizardWelcomePageViewModel}">
<View:WizardWelcomePageView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:WizardSchoolclassSubjectPageViewModel}">
<View:WizardSchoolclassSubjectPageView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:WizardLessonTimesPageViewModel}">
<View:WizardLessonTimesPageView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:WizardTimeTablePageViewModel}">
<View:WizardTimeTablePageView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:WizardFinishPageViewModel}">
<View:WizardFinishPageView />
</DataTemplate>
<!-- This Style inherits from the Button style seen above. -->
<Style BasedOn="{StaticResource {x:Type Button}}" TargetType="{x:Type Button}" x:Key="moveNextButtonStyle">
<Setter Property="Content" Value="Next" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsOnLastPage}" Value="True">
<Setter Property="Content" Value="Finish}" />
</DataTrigger>
</Style.Triggers>
</Style>
<ViewModel:WizardMainViewModel x:Key="WizardMainViewModelID" />
</UserControl.Resources>
<Grid DataContext="{Binding ., Source={StaticResource WizardMainViewModelID}}" >
<Grid.RowDefinitions>
<RowDefinition Height="310*" />
<RowDefinition Height="51*" />
</Grid.RowDefinitions>
<!-- CONTENT -->
<Grid Grid.Row="0" Background="LightGoldenrodYellow">
<HeaderedContentControl Content="{Binding CurrentPage}" Header="{Binding Path=CurrentPage.DisplayName}" />
</Grid>
<!-- NAVIGATION BUTTONS -->
<Grid Grid.Row="1" Background="Aquamarine">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button Command="{Binding MovePreviousCommand}" Content="Previous" />
<Button Command="{Binding MoveNextCommand}" Style="{StaticResource moveNextButtonStyle}" Content="Next" />
<Button Command="{Binding CancelCommand}" Content="Cancel" />
</StackPanel>
</Grid>
</Grid>