WPF Caliburn.Micro and TabControl with UserControls issue

Viewed 9421

I'm pretty sure this has been answered somewhere, but I can't seem to find it for the life of me.

I'm trying to use a TabControl to switch between UserControls (each tab is different, so not using Items)

Here's the breakdown: I have my mainview, and 3 usercontrols. Mainview has a tab control - each tab should display a different user control.

I could easily just set the tabcontrol contect to the usercontrol using But then it isn't bound to the viewmodel, only the view.

So I'm using Conductor in my VM, and ActivateItem. Here's where it starts to get weird / frustrating. Application starts with Tab0 selected, but Tab2 (last tab) content. Click on any other tab, loads the correct ViewModel for that tab. Click back to Tab0, loads the correct content there as well.

How do I get this to stop? Also, I'd really like it if switching tabs doesn't re-initialize the viewmodel again, clearing out fields that have already been entered.

Anyways, here's some of my source, I'm going to just drop this here and work on something else before I break my mouse.

View:

<TabControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row ="1">
        <TabItem Header="PC Information">
            <Grid>
                <ContentControl x:Name="LoadRemoteInfo" cal:View.Model="{Binding ActiveItem}"/>
            </Grid>
        </TabItem>
        <TabItem Header="Remote Tools">
            <Grid>
                <ContentControl x:Name="LoadRemoteTools" cal:View.Model="{Binding ActiveItem}"/>
            </Grid>
        </TabItem>
        <TabItem Header="CHRemote">
            <Grid>
                <ContentControl x:Name="LoadCHRemote" cal:View.Model="{Binding ActiveItem}"/>
            </Grid>
        </TabItem>

    </TabControl>

and the ViewModel:

class MainViewModel : Conductor<object>
{
    RemoteInfoViewModel remoteInfo = new RemoteInfoViewModel();
    RemoteToolsViewModel remoteTools = new RemoteToolsViewModel();
    CHRemoteViewModel chRemote = new CHRemoteViewModel();

    public MainViewModel()
    {
        ActivateItem(remoteInfo);
    }

    public void LoadRemoteInfo()
    {
        ActivateItem(remoteInfo);
    }

    public void LoadRemoteTools()
    {
        ActivateItem(remoteTools);
    }

    public void LoadCHRemote()
    {
        ActivateItem(chRemote);
    }
}
2 Answers

Just to add to Patryk Ćwiek's great answer!

If you are already using Caliburn Mirco and don't want to add more dependencies, you can use their SimpleContainer in place of SimpleInjector or AutoFac.

Just register the implementations like so:

container.AllTypesOf<IMainScreenTabItem>(Assembly.GetExecutingAssembly());
Related