Adding controls to a TabWorkspace

Apr 25, 2007 at 8:22 PM
I am adding a view to a TabWorkspace via the main menu like this:

private void ExtendMenu()
    {
      ToolStripMenuItem item = new ToolStripMenuItem("My Menu Item");
      WorkItem.Parent.UIExtensionSites["Tools"].Add(item);
 
      WorkItem.Commands[CommandNames.ShowBalanceSheetManager].AddInvoker(item, "Click");
    }
 
[CommandHandler(CommandNames.ShowMyItem)]
    public void MenuToolsMyMenuItem_Click(object sender, EventArgs e)
    {
      IAccountView accountView = WorkItem.SmartParts.AddNew<AccountView>();     
      WorkItem.Workspaces[Constants.WorkspaceNames.RightWorkspace].Show(accountView); 
     }

The problem is that whenever everytime I click on My Menu Item another tab is added to TabWorkspace with the view. Is there a pattern to use to ensure that the item is only added one time or that the TabWorkspace is cleared before adding the view?

Thank you
Apr 26, 2007 at 10:33 AM
Hi jsavold,
i use the following pattern to Create a new/Activate an existing element in WorkSpace.:

this is the command handler

 [CommandHandler(Constants.CommandNames.ShowCustomersList)]
        public void ShowCustomersList(Object sender, EventArgs e)
        {
            ICustomersListView customerListView;
            customerListView = GetOrCreateWorkItemElement<CustomersListView>(CustomerListViewName);
            ShowOrActivateInMainWorkspace(customerListView);
        }

here are the routines used in the command handler.
        // Show a new Smartpart or activate an existing one (if found)
        private void ShowOrActivateInMainWorkspace(object smartPart)
        {
            if(this.WorkItem.RootWorkItem.Workspaces[Constants.WorkspaceNames.MainWorkspace].SmartParts.Contains(smartPart))
                this.WorkItem.RootWorkItem.Workspaces[Constants.WorkspaceNames.MainWorkspace].Activate(smartPart);
            else
                this.WorkItem.RootWorkItem.Workspaces[Constants.WorkspaceNames.MainWorkspace].Show(smartPart);
        }
 
        // Get an existing item in Items or create a new one
        private T GetOrCreateWorkItemElement<T>(string elementID)
        {
            if (this.WorkItem.Items.Contains(elementID))
                return this.WorkItem.Items.Get<T>(elementID);
            return this.WorkItem.Items.AddNew<T>(elementID);
        }
 

it is simple:
if it found the view in the items collection of the workitem it simply take the existing instance and activate it in workspace. Else it create a new one and add to WorkSpace.

Hope this help.
Alessio
Apr 26, 2007 at 4:14 PM
Thanks Alessio,
That was the solution I was looking for. Easy once you see it in front of you.
Apr 26, 2007 at 4:32 PM
I refactored your ShowOrActivateInMainWorkspace method to the following:

    #region FillWorkspace
    private void FillWorkspace(object smartPart, string workspaceName)
    {
      SmartPartInfo info = new SmartPartInfo();
      FillWorkspace(smartPart, workspaceName, info); 
    }
 
    private void FillWorkspace(object smartPart, string workspaceName, ISmartPartInfo info)
    {
      if (this.WorkItem.RootWorkItem.Workspaces[workspaceName].SmartParts.Contains(smartPart))
        this.WorkItem.RootWorkItem.Workspaces[workspaceName].Activate(smartPart);
      else
        this.WorkItem.RootWorkItem.Workspaces[workspaceName].Show(smartPart, info);
    }
    #endregion FillWorkspace
 

This makes it more generic so it can fill any Workspace and ads the ability to use a SmartInfo object.

Thanks Again