Peppermintology
Peppermintology

Reputation: 10210

Screen of nested Conductor not being activated

I have a ShellViewModel which inherits from Conductor<Workspace>.Collection.OneActive and a ShellView which has a ContenControl with a x:Name attribute of ActiveItem.

Note that Workspace inherits Screen.

ShellViewModel

public class ShellViewModel : Conductor<Workspace>.Collection.OneActive
{
    ShellViewModel(IEnumerable<Workspace> items)
    {
        this.Items = items;
        // below is not how I activate, just an example for descriptive purposes
        this.ActivateItem(this.Items.FirstOrDefault(e => e.Id == "Container"));
    }
}

ShellView

<ContentControl x:Name="ActiveItem" />

In the above, my Items collection is successfully populated with objects of Workspace and the object of Workspace is successfully shown in the ContentControl when ActivateItem is called.

The ActiveItem is a Screen and not a Conductor<Workspace> which it contains an ObservableCollection<PanelViewModel>. My ContainerView has an ItemsControl with its ItemsSource bound to the PanelViewCollection and its template override to display using a `UniformGrid.

ContainerViewModel

public class ContainerViewModel : Screen
{
    // get/set implantation missed for brevity
    public ObservableCollection<PanelViewModel> PanelViewCollection
    {
        get;
        set;
    }

    public void AddPanelViewModel()
    {
        var @new = new PanelViewModel();
        this.PanelViewCollection.Add(@new);
    }
}

ContainerView

<ItemsControl ItemsSource="{Binding PanelViewCollection}>
    <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
               <UniformGrid/>
          </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

A Button on my ContainerView calls the AddPanelViewModel function on the ContainerViewModel and a new PanelViewModel is added to the collection and it becomes visible on the ContainerView.

Up to this point everything appears to be working OK.

The PanelViewModel inherits from Conductor<Workspace>.Collection.OneActive and the PanelView has a ContenControl with a x:Name attribute of `ActiveItem.

PanelViewModel

public class PanelViewModel : Conductor<Workspace>.Collection.OneActive
{
    PanelViewModel(IEnumerable<Workspace> items)
    {
        this.Items = items;
        // below is not how I activate, just an example for descriptive purposes
        this.ActivateItem(this.Items.FirstOrDefault(e => e.Id == "PanelA"));
    }
}

PanelView

<StackPanel>
    <TextBlock Text="There be treasure here!" />
    <ContentControl x:Name="ActiveItem" />
</StackPanel>

Whilst the PanelView is displayed (I see treasure here) the ActiveItem is not being shown and I think it has something to do with activation, as the OnActivate method of the Workspace being activated is not being called.

What have I missed?

Edit

I have committed an example to a Git repo for those who my be inclined to review it:

Upvotes: 2

Views: 870

Answers (1)

Peppermintology
Peppermintology

Reputation: 10210

After further reading I believe there were two issues with my implementation described in the OP.

  1. My ContainerView ItemsControl.ItemTemplate DataTemplate was incorrect. I appeared to be displaying the View rather than the ViewModel.
  2. As my ContainerView was partially managing Screen lifetimes, it should have been inheriting from Conductor which it was not.

I have committed a working implementation to the Git repo for anyone that may come across the same or a similar issue.

Upvotes: 3

Related Questions