OnActivate and OnDeactivate not working on a child view

Topics: Bugs, Getting Started
Mar 7, 2013 at 3:39 PM
I modified the MDI example to demonstrate my problem

Initially, I only changed TabViewModel by adding the following two functions:
protected override void OnActivate()
        {
            System.Diagnostics.Debug.WriteLine("Active " + DisplayName);          
            base.OnActivate();
        }

        protected override void OnDeactivate(bool close)
        {
            System.Diagnostics.Debug.WriteLine("Inactive " + DisplayName);        
            base.OnDeactivate(close);
        }
This works as expected and I can see the messages in Debug console.

Now, I want to have the tabcontrol in another view contained in the shell view.
So I added another Child view model and view. Now even thought the tab items are added and removed as expected, the OnActivate and OnDeactivate are not called. Am I doing something wrong?
namespace Caliburn.Micro.SimpleMDI {
    public class ShellViewModel : PropertyChangedBase
    {
        private ChildViewModel _childViewModel = null;
        
        public ChildViewModel ChildViewModel
        {
            get
            {
                return _childViewModel;
            }
            set
            {
                _childViewModel = value;
                NotifyOfPropertyChange(() => ChildViewModel);
            }
        }

        public ShellViewModel()
        {
            ChildViewModel = new ChildViewModel();
        }
    }
}
<Window x:Class="Caliburn.Micro.SimpleMDI.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cal="http://www.caliburnproject.org"
        Width="640"
        Height="480">
    <DockPanel>
        <ContentControl cal:View.Model="{Binding Path=ChildViewModel, Mode=TwoWay}" />        
    </DockPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Caliburn.Micro.SimpleMDI
{
    public class ChildViewModel : Conductor<IScreen>.Collection.OneActive
    {
        int count = 1;

        public void OpenTab()
        {
            ActivateItem(new TabViewModel
            {
                DisplayName = "Tab " + count++
            });
        }

        public void CloseSelectedTab()
        {
            DeactivateItem(ActiveItem, true);
        }
    }
}
<UserControl x:Class="Caliburn.Micro.SimpleMDI.ChildView"
             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:cal="http://www.caliburnproject.org"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <DockPanel>            
            <Button x:Name="OpenTab"
                Content="Open Tab" 
                DockPanel.Dock="Top" />
            <Button x:Name="CloseSelectedTab"
                Content="Close Tab" 
                DockPanel.Dock="Top" />
            <TabControl x:Name="Items">
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding DisplayName}" />
                            <Button Content="X"
                                cal:Message.Attach="DeactivateItem($dataContext, 'true')" />
                        </StackPanel>
                    </DataTemplate>
                </TabControl.ItemTemplate>
            </TabControl>
        </DockPanel>
    </Grid>
</UserControl>
namespace Caliburn.Micro.SimpleMDI {
    public class TabViewModel : Screen
    {
        protected override void OnActivate()
        {
            System.Diagnostics.Debug.WriteLine("Active " + DisplayName);
            base.OnActivate();
        }

        protected override void OnDeactivate(bool close)
        {
            System.Diagnostics.Debug.WriteLine("Inactive " + DisplayName);
            base.OnDeactivate(close);
        }
        
        public TabViewModel()
        {
            System.Diagnostics.Debug.WriteLine(DisplayName);
        }
    
    }
}
Mar 8, 2013 at 1:00 PM
Try adding ChildViewModel.ConductWith(this); to your ShellViewModel's constructor.
Maybe this helps, but haven't tested.
Mar 10, 2013 at 6:20 PM
Thanks.
This worked fine.