views:

238

answers:

1

I've got a page manager that keeps a collection of pages (usercontrols), sends itself to each page which can thus call its SwitchPage method at anytime enabling me to put in links from one page to another. This works well and allows me to have a quick menu etc.

public partial class PageManager : UserControl
{
    private Dictionary<string, UserControl> Pages = new Dictionary<string, UserControl>();

    private string defaultPageIdCode = "page1";
    private UserControl currentPage;
    private string currentPageIdCode;

    public PageManager()
    {
        InitializeComponent();

        LoadPages();
        SwitchPage(defaultPageIdCode);
    }

    private void LoadPages()
    {
        Pages.Add("page1", new Page1(this));
        Pages.Add("page2", new Page2(this));
    }

    public void SwitchPage(string pageIdCode)
    {
        currentPageIdCode = pageIdCode;
        currentPage = Pages[pageIdCode];
        PageArea.Content = currentPage;
    }
}

However, each page (UserControl) has repeated functionality in it, e.g. saving the PageManager object internally, which I would like to put in a base class:

Page1.xaml:

<UserControl x:Class="TestPageManager23434.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <StackPanel Background="White" 
             Width="400"
             Height="400"                
                >
        <TextBlock Text="this is page1"/>
        <Button Content="go to page 2" Click="Button_Click"
                HorizontalAlignment="Left"
                Width="200"
                Height="30"
                />
    </StackPanel>
</UserControl>

Page1.xaml.cs:

public partial class Page1 : UserControl
{
    private PageManager pageManager;

    public Page1(PageManager pageManager)
    {
        this.pageManager = pageManager;
        InitializeComponent();
    }

    private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        pageManager.SwitchPage("page2");
    }
}

Page2.xaml:

<UserControl x:Class="TestPageManager23434.Page2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <StackPanel Background="White"
                Width="400"
                Height="400"
                >
        <TextBlock Text="this is page2"/>
        <Button Content="go back to page 1" Click="Button_Click"
                HorizontalAlignment="Left"
                Width="250"
                Height="30"
                />
    </StackPanel>
</UserControl>

Page2.xaml.cs:

public partial class Page2 : UserControl
{
    private PageManager pageManager;

    public Page1(PageManager pageManager)
    {
        this.pageManager = pageManager;
        InitializeComponent();
    }

    private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        pageManager.SwitchPage("page1");
    }
}

How can make each UserControl inherit a base class? It doesn't work since each UserControl has XAML which can't be inherited. And if I try to inherit from a plain class that inherits UserControl then it tells me:

Partial declarations of 'TestPageManager23434.Page2' must not specify different base classes

+5  A: 

Instead of declaring the root element as UserControl, declare it as your derived class. You will need to specify the namespace as well e.g.

<local:PageBase x:Class="TestPageManager23434.Page2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestPageManager23434">
</local:PageBase>
Phil Devaney
Obviously the class in the code behind should then also inherit from the same base class...
Pieter Breed
Actually, I discovered the other day that you don't need to specify the base class in the code behind, and Resharper will actually flag it as a redundancy. Only one part of a partial class definition must specify the base class, thought its fine to specify it on multiple parts as long as they match.
Phil Devaney
Edward Tanguay