CAB - Support for Custom Commands
In my last post I've talked about how to expose an OutlookBar as UIExtensionSite, during this post I would like to cover what are the needed actions needed to be added in order to support also the ability of using the command invokers with our OutlookBar.
The idea is the same... in order for the CAB infrastructure to recognize our OutlookBar we need to introduce to the infrastructure an EventCommandAdapter.
The EventCommandAdapter is used to link an event name like "Click" event to the Button or any other UI Item that you are adapting to.
public
class
OutlookBarButtonCommandAdapter
:
EventCommandAdapter<OutlookBarButton>
{
public
OutlookBarButtonCommandAdapter() :
base()
{}
public
OutlookBarButtonCommandAdapter(OutlookBarButton
button,string
eventName) :
base(button,
eventName)
{}
protected
override
void
OnCommandChanged(Command
command)
{
base.OnCommandChanged(command);
foreach
(KeyValuePair<OutlookBarButton,List<string>> pair
in
Invokers)
{
pair.Key.Enabled = (command.Status ==
CommandStatus.Enabled);
}
}
}
The constructor passes the call to the base constructor.
The OnCommandChanged method is where you write you specific code for controlling key characteristics of your UI Control such as if the Button should be Enabled or Disabled, the pair.key represent the OutlookBarButton and here you can set various properties of this button.
Note: in order to make the
Herre Kuijpers Outlook Bar suitable for attaching event handlers to the buttons I had
to do a minor change to the original OutlookBar code, the
change was cause because originally the control had a click
event on the control which was using event args of the click
to find out which button was clicked. The change that I've
made was to add a Click event to the OutlookBarButton and
expose a public DoClick method that will be invoke from the
bar on the selected button.
Normally I would have coded
it myself much more clearer but then... my main show here is
not about the control itself but how to integrate it with
CAB.
public
class
OutlookBarButton
{
public
event
EventHandler
Click;
public
void
DoClick()
{
if (Click!=null)
Click.Invoke(this,EventArgs.Empty);
}
// the rest of the code is the same
}
public
partial
class
OutlookBar :
UserControl
{
private void OutlookBar_Click(object sender, EventArgs e)
{
// Same method... Same Code
SelectedButton.DoClick();
}
}
Ok so you have a patched OutlookBar and OutlookBarButtonCommandAdapter how do you introduce the adapter to the CAB infrastructure ?
You need to register the OutlookBarButtonCommandAdapter at the MappingService, this is being done on the ShellApplication AfterShellCreated or on the layout module Run:
ICommandAdapterMapService
mapService = RootWorkItem.Services.Get <ICommandAdapterMapService>();
mapService.Register(typeof(OutlookBarButton), typeof(OutlookBarButtonCommandAdapter));
In order to attach invoker in your module declare a command name constant such as:
public
class
CommandNames :
Experts4D.SampleModule.Interface.Constants.CommandNames
{
public
const
string
SampleCommand =
"SampleCommand";
}
Register the new command for the button as part as you extension code:
OutlookBarButton
btnShowCalendar =
new
OutlookBarButton();
btnShowCalendar.Text =
"New Module Button";
WorkItem.UIExtensionSites[Interface.Constants.UIExtensionSiteNames.MainOutlookBar].Add
<OutlookStyleControls.OutlookBarButton>(btnShowCalendar);
WorkItem.Commands[Constants.CommandNames.SampleCommand].AddInvoker(btnShowCalendar,
"Click");
And then add a command handler in your code:
[CommandHandler(Constants.CommandNames.SampleCommand)]
public
void
HistCaneldar(object
sender,
EventArgs
e)
{
MessageBox.Show("Command Clicked");
}
In my next post I'll show you how you can use a simple design solution in order to decouple between the module and the UIExtensionSite as the module doesn't need to be aware that you are implementing your OutlookBar using OutlookBarButtons.