How To: Get the active view across multiple workspaces in a SCSF application

Last week I saw a question in the SCSF forum about getting the active view in an application with several types of workspaces. In his post CAB: Solving The Active View Problem, Chris Holmes tackles the scenario within the context of a single workspace. I found a way to apply another solution that gets the Active View by monitoring all workspaces. I created the ActiveViewMonitorService service that is in charge of doing this.

I made a sample application that shows how this service works. Download from here.

Change the application’s active view by clicking in the TextBox of each view. Then click in the Active View button in the main menu bar to verify the active view’s name.

Implementation Details

The ActiveViewMonitorService service monitors the SmartPartActivated and Enter events for each workspace in the application. The SmartPartActivated allows to know when the user is changing the active view in the context of the same workspace and the Enter event allows to know when the user is changing to a view in another workspace. The following is the service implementation:

public interface IActiveViewMonitorService
{
    void AddWorkspaceToMonitor(IWorkspace workspace);
    object ActiveView { get; }
}

public class ActiveViewMonitorService : IActiveViewMonitorService
{
    #region IActiveViewMonitorService Members

    public void AddWorkspaceToMonitor(IWorkspace workspace)
    {
        workspace.SmartPartActivated += new EventHandler<WorkspaceEventArgs>(OnSmartPartActivated);
        ActiveView = workspace.ActiveSmartPart;

        Control wk = workspace as Control;
        if (wk != null)
        {
            wk.Enter += new EventHandler(OnEnter);
        }
    }

    public object ActiveView { get; private set; }

    #endregion

    private void OnSmartPartActivated(object sender, WorkspaceEventArgs e)
    {
        ActiveView = e.SmartPart;
    }

    private void OnEnter(object sender, EventArgs e)
    {
        IWorkspace wk = sender as IWorkspace;

        if (wk != null)
        {
            ActiveView = wk.ActiveSmartPart;
        }
    }
}

Steps

  1. Register it as a service in the RootWorkItem.
  2. Add the workspaces you want to monitor using the AddWorkspaceToMonitor method (you can do this by adding an event handler to the Initialized event of the RootWorkItem in the ShellApplication class).
    // ShellApplication class
    protected override void AfterShellCreated()
    {
        RootWorkItem.Initialized += new EventHandler(RootWorkItem_Initialized);
    }
    
    private void RootWorkItem_Initialized(object sender, EventArgs args)
    {
        IActiveViewMonitorService activeViewMonitorService = RootWorkItem.Services.Get<IActiveViewMonitorService>();
    
        foreach (KeyValuePair<string, IWorkspace> key in RootWorkItem.Workspaces)
        {
            activeViewMonitorService.AddWorkspaceToMonitor(key.Value);
        }
    }

  3. Get the active view using the ActiveView property of the service.
Note: The ActiveViewMonitorService service accepts Workspaces that inherit from the Control class.

Enjoy

Technorati Tags: ,



No Comments

Leave a Reply