• CAB: Use the Outlook Bar in your CAB applications

    Published by on May 1st, 2006 2:55 pm under CAB

    17 Comments

    UPDATE: I moved the code to codeplex. http://www.codeplex.com/cabextensions.

    ———-

    A frecuently requested feature in the CAB community is a navigation control like Microsoft Outlook’s bar. Chris Holmes posted a few days ago a nice approach on how to achieve this using CAB:

    cab1

    In CAB Reference Implementation 2 (Global Bank Branch WorkBench), an IconTabWorkspace is introduced. The functionallity of the workspace is similar to Outlook’s bar, but it just displays icons (ToolStripButtons):
    cab2

    At Southworks, we liked both ideas and put them together to create an OutlookBarWorkSpace:

    cab3 cab4
    OutlookBar workspace showing the Mails smartpart Calendar module was selected and the smartpart has been shown
    cab5 cab6
    Use of the splitter Show more/fewer buttons

    You can download it from here.

    Usage

    Use it as every CAB Workspace! Add SmartParts using:

    • void Show(object smartPart) and having your SmartPart implement ISmartInfoProvider or 
    • void Show(object smartPart, ISmartPartInfo smartPartInfo)

    But take into account that in both cases you have to provide an OutlookBarSmartPartInfo, which will contain needed information to create the buttons.
    OutlookBarSmartPartInfo has the following members in addition to those included in the SmartPartInfo base class:

    • Icon: bitmap to be displayed in the button.
    • (Optional) ImageTransparentColor: transparent color on the item’s icon for images that support transparency
    • (Optional) EventTopicName: EventTopic that will be raised when clicking the button. This is useful, for example, when you need to update another workspace (much like what MS Outlook does).

    Apart from these members, the OutlookBarWorkspace uses the Title property to set the button’s text.

    Disclaimer:
    This code is provided "AS IS" with no warranties, and confers no rights.

    Acknowledgments
    - The implementation of the stack strip is based on a sample written by Joe Stegman
    - Mariano Szklanny helped writing the workspace implementation
    - The office icons might be used only if you have a valid Microsoft Office license

    • Chris Holmes

      Awesome work Matias! I am so happy to see you take this and run with it!

      This is exactly what I hoped for when I posted my code. Nice work!

    • http://

      Excellent work. This is just fantastic! Thank you so much.

    • http://

      You and I had exactly the same idea! The sample with HeaderStrip, StackStrip, etc. + CAB + Chris Holmes’ initial start = awesome.

      Though, I’ve approached it differently, making an OutlookBar that is both a Workspace and a UIExtensionSite. I hope to get a blog up and going to share the code soon.

      Great stuff. Thanks for this code, Matias.

    • http://

      Matias,
      Excellent work.

      Found a bug on line 202:
      string eventTopic = _topics[button.Text];

      Crashes if _topics doesn’t contain given key.
      Changed this line to:
      if( _topics.ContainsKey( button.Text ) )
      and all is good.

      Cheers, Greg.

    • matiaswoloski

      Hi Greg,

      good catch.
      Indeed, for better perf, it should be implemented like this
      http://weblogs.asp.net/fbouma/archive/2006/05/02/444779.aspx

      Thanks,
      Matias

    • http://

      It will be cool if this workspace is dockable/pinnable.

    • http://

      Can you provide an example on how to use EventTopicName?

    • Matias Woloski

      The Event Publication feature of the OutlookBar workspace is used like this:

      OutlookSmartPartInfo ospi = new OutlookSmartPartInfo();
      ospi.EventTopicName = “OnMailPressed”;
      ospi.Title = “Mail”;
      ospi.Icon = Resources.MailIcon;
      ws.Show( myView, ospi );

      The workspace will associate the event topic with the click of the Mail button. So in your Mail ModuleController you could have

      [EventSubscription(“OnMailPressed”)]
      public void OnMailPressed(object sender, EventArgs e) {
      // do something because the Mail button was pressed
      }

      Matias

    • http://

      I want to change theme to classic (gray) in windows XP…is it possible? If yes then how? Can someone share their code?

    • http://

      How to have the Mail Button(pressed in orange) be default button on the load like outlook?

    • http://

      Meenu,

      This is how I resolved the issue:

      Override the OnLoad Event Handler in the class, OutlookBarWorkspace, and add the following code after the call to base.OnLoad(e);

      // Cast ActiveSmartPart to SmartPartInfoProvider
      ISmartPartInfoProvider activeSmartPartProvider = this.ActiveSmartPart as ISmartPartInfoProvider;

      // Obtain SmartPart details from the SmartPartInfo object
      ISmartPartInfo activeSmartPartInfo = activeSmartPartProvider.GetSmartPartInfo(typeof(OutlookBarSmartPartInfo));

      // Cycle through the SmartPart collection and activate the ToolStripButton with the matching title.
      foreach (ToolStripButton toolStripButton in _smartParts.Values)
      {
      toolStripButton.Checked = activeSmartPartInfo.Title == toolStripButton.Text;
      }

      Anyone disagree with this approach?

      David

    • http://

      I realy need an working example of the great looking OutlookBarWorkspace. I have no idea where to start adding buttons and smartparts. In the Shell? I managed to add just one button in the WorkItem.Run() method, but i assume it is not the right place.
      Thanks for help
      Ralf

    • http://

      Great work! I’m just starting with CAB and this really helped.

      One question: How can I set a particular button/smartpart to be activated at load? I get the header for the last one added but the smartpart isn’t displayed.

    • MikeWo

      Meenu, HCGL, David:

      I was also trying to be able to set the header to specific smartpart. It seemed like the Activate function should do the trick, but while it did make the related smartpart the active smart part, it didn’t update the header. It called the OnSmartpartActivitated method in OutlookBarWorkspace but that did a cast on the smart part to ISmartPartInfo to get the text to set the header, which was never the case for me since I was passing a reference to the smartPart itself, not the smartPartInfo. I added a line to the Active method, it now looks like this:

      public void Activate(object smartPart)
      {
      _deckWorkspace.Activate(smartPart);
      OnSmartPartActivated(smartPart);
      ToolStripButton relatedButton;
      if (_smartParts.TryGetValue(smartPart, relatedButton))
      {
      _headerLabel.Text = relatedButton.Text.Trim();
      } }

      No need to loop through the smart parts collections to find it. I feel like I’m missing something as to why the Activate seems to have expected a SmartPartInfo though.

    • MikeWo

      Whoops, forgot the out in the TryGetValue method. That line should look like this:

      if (_smartParts.TryGetValue(smartPart, out relatedButton))

    • http://

      Hi,

      I am trying to create a Outlook workspace from scratch using WPF. Can you guide me how to start with this. Right now I have created OutlookWS.cs and also implementing the OutlookWSSmartPartInfo.cs.

      What are you using for buttons? Are you using tab workspace/ deck workspace inside ur workspace.

      Please let me know, this is urgent.

      Thanks for ur time.

    • ChrisA

      How do I implement this with Outlook 2002?
      (vrsn. 10.3513…) on Windows XP
      Thanks,
      ChrisA.

Tags