Have you ever thought how easy can be to build a Wizard leveraging the power of WPF data templates and data template selectors? take a look at this ViewModel:
class WelcomeWizardViewModel : AbstractViewModel
{
        AbstractWizardPage[] pages;
        
        public AbstractWizardPage CurrentPage
        {
            get { return this.GetPropertyValue( () => this.CurrentPage ); }
            private set { this.SetPropertyValue( () => this.CurrentPage, value ); }
        }

        public void MoveToNextPage()
        {
            var idx = Array.IndexOf( this.pages, this.CurrentPage );
            var next = this.pages[ idx + 1 ];
            this.CurrentPage = next;
            this.CurrentPage.OnNavigatedTo( WizardNavigationDirection.Forward );
        }

        public void MoveToPreviousPage()
        {
            var idx = Array.IndexOf( this.pages, this.CurrentPage );
            var prev = this.pages[ idx - 1 ];
            this.CurrentPage = prev;
            this.CurrentPage.OnNavigatedTo( WizardNavigationDirection.Backward );
        }
}
We encapsulated all the logic of the Wizard in the view model, and obviously we have a bunch of classes the inherits from AbstractWizardPage.
The problem now is how can we associate a view to each page? nothing more than this:
<ContentControl Content="{Binding Path=CurrentPage}" Margin="10">
    <ContentControl.ContentTemplateSelector>
        <ts:ConventionTemplateSelector />
    </ContentControl.ContentTemplateSelector>
</ContentControl>
where the template selector is something like:
public class ConventionTemplateSelector : DataTemplateSelector
{
    Dictionary<Object, DataTemplate> templatesCache = new Dictionary<Object, DataTemplate>();

    public ConventionTemplateSelector()
    {
        this.CacheTemplates = true;
        this.ConventionHandler = new LayoutTemplateConventionHandler();
    }

    public Boolean CacheTemplates { get; set; }

    public AbstractTemplateConventionHandler ConventionHandler { get; set; }

    public override DataTemplate SelectTemplate( object item, System.Windows.DependencyObject container )
    {
        if( item != null )
        {
            DataTemplate template;
            if( !this.templatesCache.TryGetValue( item, out template ) )
            {
                var templateType = this.ConventionHandler.GetTemplateTypeFor( item );

                template = new DataTemplate()
                {
                    VisualTree = new FrameworkElementFactory()
                    {
                        Type = templateType
                    }
                };

                if( this.CacheTemplates )
                {
                    this.templatesCache.Add( item, template );
                }
            }

            return template;
        }

        return base.SelectTemplate( item, container );
    }
}
We have e template selector that delegates to a convention the way to determine which will be the type of the layout we want at runtime, here we are using FrameworkElementFactory in order to generate a DataTemplate that will be linked to a Type.
The abstract template convention handler is nothing more then a really simple class:
public abstract class AbstractTemplateConventionHandler
{
    public abstract Type GetTemplateTypeFor( Object item );
}
and default convention handler is:
class LayoutTemplateConventionHandler : AbstractTemplateConventionHandler
{
    public override Type GetTemplateTypeFor( object item )
    {
        var type = item.GetType();
        var layoutTypeName = String.Format( "{0}.{1}Layout", type.Namespace, type.Name );
        var layoutType = Type.GetType( layoutTypeName, true );

        return layoutType;
    }
}
We are basically looking for a type in the same namespace of the item type with a name that ends with layout, so having a page called WelcomePage we will look for a WelcomePageLayout type to be used as the template view.
.m