Command Not Executing

Oct 2, 2007 at 5:31 PM
I have a Shell that is WinForms and an LayoutModule that is SCSFContrib WPF.

In Library's SmartClientApplication class, I register the UIElementCommandAdapter in the AfterShellCreated:

protected override void AfterShellCreated()
{
base.AfterShellCreated();

ICommandAdapterMapService commandAdapterMapService = RootWorkItem.Services.Get<ICommandAdapterMapService>();
commandAdapterMapService.Register(typeof(UIElement), typeof(UIElementCommandAdapter));

IUIElementAdapterFactoryCatalog uiElementAdapterFactoryCatalog = RootWorkItem.Services.Get<IUIElementAdapterFactoryCatalog>();
uiElementAdapterFactoryCatalog.RegisterFactory(new ItemsControlUIAdapterFactory());
}

In InfrastructureModule's ModuleController, I create a WPF button and add it to my main toolbar:

Button button = new Button();
button.Content = "Directory";

workItem.UIExtensionSitesUIExtensionSiteNames.MainToolbar.Add<Button>(button);
workItem.CommandsCommandNames.ShowDirectory.AddInvoker(button, "Click");

Also in the ModuleController, I add a CommandHandler:

CommandHandler(CommandNames.ShowDirectory)
public void OnShowDirectory(object sender, EventArgs e)
{
//Do something
}


When I run the application and click on the button, nothing happens.

After calling the AddInvoker method, I do a QuickWatch and I can see that there is one invoker and that it is using the UIElementCommandAdapter:

- workItem.CommandscommandName {Microsoft.Practices.CompositeUI.Commands.Command} Microsoft.Practices.CompositeUI.Commands.Command
- Adapters Count = 1 System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Practices.CompositeUI.Commands.CommandAdapter>
- 0 {SCSFContrib.CompositeUI.WPF.CommandAdapters.UIElementCommandAdapter} Microsoft.Practices.CompositeUI.Commands.CommandAdapter {SCSFContrib.CompositeUI.WPF.CommandAdapters.UIElementCommandAdapter}
+ SCSFContrib.CompositeUI.WPF.CommandAdapters.UIElementCommandAdapter {SCSFContrib.CompositeUI.WPF.CommandAdapters.UIElementCommandAdapter} SCSFContrib.CompositeUI.WPF.CommandAdapters.UIElementCommandAdapter
InvokerCount 1 int
+ Non-Public members
+ Raw View
Name "ShowDirectory" string
Status Enabled Microsoft.Practices.CompositeUI.Commands.CommandStatus
+ TraceSource {System.Diagnostics.TraceSource} System.Diagnostics.TraceSource
+ Non-Public members


This should just work. Is there something going on because the toolbar is a WPF control instead of a WinForms control?

Your help is appreciated.


Mark


Oct 2, 2007 at 6:27 PM
Check if ExecuteAction event of the Command (as it is returned by workItem.Commands[]) has a subscriber. If it doesn't, I would suspect that your CommandHandler attribute does not get processed, for some reason.
Also double check count of commands you have at the rootWorkItem, to make sure you add invoker to the same command that you subscribe your method handler to.

WPF/WinForms should not be an issue, as long as you can click the button, it should hit the UIElementCommandAdapter.

Also, I am not sure if it matters, but you can try to change event handler signature to match the RoutedEventHandler, i.e. void handler(object sender, RoutedEventArgs e)

Roman V. Gavrilov
Oct 2, 2007 at 11:32 PM
I solved the issue. Here is what happened. I created a ShellExtensionService that had a method that would be used to add toolbar buttons:

public void AddNavigation(string text, string commandName)
{
Button button = new Button();
button.Content = text;

workItem.UIExtensionSitesUIExtensionSiteNames.MainToolbar.Add<Button>(button);
workItem.CommandscommandName.AddInvoker(button, "Click");
}

I used ServiceDependency to set the WorkItem and since this service was added to the RootWorkItem so that any Module could use it, the Command Invoker was added to the RootWorkItem.Commands collection.

Now, in the ModuleController for a Module, I got access to the ShellExtensionService and added a button:

ShellExtensionService.AddNavigation(Resources.DirectoryLinkText, CommandNames.ShowDirectory);

This ModuleController also had a CommandHandler:

CommandHandler(CommandNames.ShowDirectory)
public void OnShowDirectory(object sender, EventArgs e)
{
//Do something
}


When the ModuleController was created the CommandHandler attribute was processed and added to the child WorkItem.

It was this mismatch of the Command Invoker being added to the RootWorkItem and the CommandHandler added to the child WorkItem that prevented the command for executing.

To fix this, I pass the WorkItem to the AddNavigation method and use that.

Thanks for the hints that helped me track this down.

Mark
Oct 4, 2007 at 2:35 AM
The problem is the order - since your module controller is executed before you invoke AddNavigation - you have command created at the child level first, as you pointed out. So that when time comes to create one by AddNavigation - it will be cretaed at the root level. Notice, if you would execute AddNavigation method first (or simply do RootWorkItem.Commands["MyCommand"]; then when ModuleController would execute - it would access the command at the root work item.

I have a strategy that allows to make command handlers in a form of objects (by decorationg a class with an attribute - CommandHandlerObject), these are instantiated at load time, which eliminate problem of the order all together.

Roman V. Gavrilov