CAB: Use the Outlook Bar in your CAB applications
May 1st, 2006
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:
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):
At Southworks, we liked both ideas and put them together to create an OutlookBarWorkSpace:
| OutlookBar workspace showing the Mails smartpart | Calendar module was selected and the smartpart has been shown |
| 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
May 1st, 2006 at 7:09 pm
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!
May 1st, 2006 at 7:48 pm
Excellent work. This is just fantastic! Thank you so much.
May 2nd, 2006 at 12:44 am
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.
May 6th, 2006 at 6:46 am
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.
May 7th, 2006 at 12:24 am
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
June 14th, 2006 at 1:41 am
It will be cool if this workspace is dockable/pinnable.
July 4th, 2006 at 3:34 am
Can you provide an example on how to use EventTopicName?
July 6th, 2006 at 12:50 am
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
July 26th, 2006 at 12:53 am
I want to change theme to classic (gray) in windows XP…is it possible? If yes then how? Can someone share their code?
July 27th, 2006 at 2:59 am
How to have the Mail Button(pressed in orange) be default button on the load like outlook?
September 22nd, 2006 at 4:49 pm
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
October 8th, 2006 at 6:45 pm
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
January 18th, 2007 at 4:39 am
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.
April 27th, 2007 at 5:47 pm
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.
April 27th, 2007 at 5:53 pm
Whoops, forgot the out in the TryGetValue method. That line should look like this:
if (_smartParts.TryGetValue(smartPart, out relatedButton))
July 25th, 2007 at 11:46 pm
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.
November 18th, 2008 at 12:56 am
How do I implement this with Outlook 2002?
(vrsn. 10.3513…) on Windows XP
Thanks,
ChrisA.