Click here to Skip to main content
12,634,712 members (23,749 online)
Click here to Skip to main content
Add your own
alternative version

Stats

98.4K views
1K downloads
99 bookmarked
Posted

Microsoft patterns & practices Composite UI Application Block (CAB) based Module Composite Mapper Service: An XML Configurable Builder for Workspaces, UIElements, Commands, and Event Publications/Subscriptions

, 30 Mar 2006 CPOL
Rate this:
Please Sign up or sign in to vote.
A Microsoft patterns & practices Composite UI Application Block (CAB) based module composite mapper service is provided including C# source code that builds Workspaces, UIElements, Commands and Event Publications/Subscriptions using an XML configuration file specified with a module.

Introduction

A Microsoft patterns & practices Composite UI Application Block (CAB) based module composite mapper service is provided including C# source code that builds Workspaces, UIElements, Commands and Event Publications/Subscriptions using an XML configuration file specified with a module. The module composite mapper service is based and executes on the CAB using a Model-View-Presenter (MVP) pattern within a proof-of-concept (POC) framework. This article and its included source code provide POC framework classes, module composite mapper service classes, module composite mapper XML configuration file syntax and examples, module composite mapper topic format guidelines, and example/template modules.

In addition to POC framework and module composite mapper service items described in further detail, the following CAB items are referenced throughout the context of this article and are defined in the CAB documentation similar to the following:

  • Module: distinct deployment unit of a CAB application; modules provide for separation of concerns such as a module that houses all (or logically grouped) infrastructure services for a specific application type or a module that houses the components that realize a specific (or logically grouped) use cases including work items, commands, events, SmartParts, services and other components
  • Shell: represents the main window of the application and provides core UI items such as a menu, toolbar, statusbar and workspaces; controls hosted in the shell (i.e., module-specified UIElements as built by the module composite mapper) are shared across the application, such as a menu item, toolbar button, or status panel (core menu items such as File-Exit and Help-About are handled by the shell itself); modules use the workspaces to display their role-specific user interface
  • Service: provides infrastructure functionality to an application (e.g., the CAB-specific module loader service and the POC framework module composite mapper service)

Proof-of-Concept Framework

The module composite mapper service is based and executes on the CAB using a Model-View-Presenter (MVP) pattern within a proof-of-concept (POC) framework. While the POC framework can be modified (or removed altogether) based on your needs, the following describes the POC framework base classes in further detail. Note that the POC framework shell uses the native CAB reflection-based module loader service against a local startup directory.

  • Module Initialization Class (e.g., <FONT color=#008080 size=2>MyModuleInit): in the POC framework, effectively only a bootstrap mechanism for the module work item (contained in the root namespace for any module)

  • Work Item Interface and Class (<FONT color=#008080 size=2>IXSWorkItem and <FONT color=#008080 size=2>XSWorkItem): the model bridge (i.e., communicates state to underlying business objects) and/or model implementation (i.e., communicates state to a persistence layer) in the MVP pattern that contains the views (i.e., SmartParts), presenters, and other components (i.e., UI elements, commands, events, services and more) that collaborate at runtime to realize a specific use case (contained in the root namespace for any module); in the POC framework, work item-based composite mappings are applied on work item build up (i.e., OnBuiltUp) ensuring that event publication/subscription is consistent with the native CAB application initialization sequence (as well as shell workspace, UI element and command initialization prior to module catalog enumeration that may rely on shell hosted items):

    <FONT color=#0000ff size=2>this.RootWorkItem.Services.Get<<FONT color=#008080 size=2>IXSModuleCompMpprService>().ApplyModuleMappings(<FONT color=#0000ff size=2>this);

    Sample screenshot

    In the POC framework, note that base work item and presenter classes provide generic events for programming efficiency and infrastructure performance optimization by alleviating the need for repetively specifying such application-wide events using the module composite mapper service (i.e., the native CAB declarative model for event publication is used).

  • Presenter Interface and Class (<FONT color=#008080 size=2>IXSPresenter and <FONT color=#008080 size=2>XSPresenter): the presenter in the MVP pattern that manages end-user displayed view(s) based on events broadcast/received or method calls made from/to the participating work item (i.e., model) (contained in the SmartParts namespace for any module); in the POC framework, presenter-based composite mappings are applied on presenter construction (which occurs on the owning XSWorkItem.Run) ensuring that views are not accessed by composite mapper classes (e.g., XSWorkspaceCompMppr) until they are actually shown:

    <FONT color=#0000ff size=2>this.workItem.RootWorkItem.Services.Get<<FONT color=#008080 size=2>IXSModuleCompMpprService>().ApplyModuleMappings(<FONT color=#0000ff size=2>this);

    Sample screenshot

    As noted previously, the POC framework base work item and presenter classes provide generic events for programming efficiency and infrastructure performance optimization by alleviating the need for repetively specifying such application-wide events using the module composite mapper service (i.e., the native CAB declarative model for event publication is used).

  • View Interface and Class (<FONT color=#008080 size=2>IXSView and XSView): the view in the MVP pattern that provides end-user display only based on method calls made from/to the participating presenter (contained in the SmartParts namespace for any module)

    Sample screenshot

Module Composite Mapper Service

The module composite mapper service allows a module developer to specify the following composite types using a module composite mapper XML configuration file (syntax is described in further detail). Note that composite is used as a generic term to describe any one of the following items:

  • Workspace: encapsulates a particular layout of controls and SmartParts, such as within tabbed pages; in the POC framework, mainly applicable to the shell presenter that provides interfaces with which to easily display module views in desired workspaces
  • UI Extension Site: identified by an extension site topic, provides a UI element adapter that serves as an extension point for any registered UI element (i.e., for adding and removing child UI elements); in the POC framework, allows a module to specify user interface element extensions within the shell (e.g., menu, toolbar and statusbar items) including end-user control over the ordering of UI elements that are added using an insert priority
  • Command: associates a command handler method that is defined on the module presenter with any command topic
  • Event Publication: specifies a method that is defined on the module work item or presenter as a publication handler for event broadcast
  • Event Subscription: specifies a method that is defined on the module work item or presenter as a subscription method for event receive

A module developer minimally interacts with the module composite mapper service through the following items only (contained in the Services.XSModuleCompMppr namespace for any module):

  • Module composite mapper XML configuration file specification
  • Workspace topic access for view display (from the workspace composite mapper for the shell... an <FONT color=#008080 size=2>XSWorkspaceCompMppr class static property)
  • User interface element access for view management (from the presenter-specific UI extension site composite mapper... an <FONT color=#008080 size=2>XSPresenter base class property)

Module Composite Mapper Service Classes

  • Module Composite Mapper Service Interface and Class (<FONT color=#008080 size=2>IXSModuleCompMpprService and <FONT color=#008080 size=2>XSModuleCompMpprService): a singleton service class that manages module composite mapper creation and delegates the application of module composite mappings (at the work item or presenter level) to the contained module composite mapper

    Sample screenshot

    The module composite mapper service is instantiated and registered in the shell application AddServices method per the following:

    <FONT color=#008080 size=2><FONT color=#008080 size=2>

    XSModuleCompMpprService service = <FONT color=#008080 size=2>XSModuleCompMpprService.CreateInstance();
    <FONT color=#0000ff size=2>this
    .RootWorkItem.Services.Add<<FONT color=#008080 size=2>IXSModuleCompMpprService>(service);

  • Module Composite Mapper Class (<FONT color=#008080 size=2>XSModuleCompMppr): builds the module composite mapper object hierarchy using the XML configuration file specified with a module (and a private XMLReader-based loader class, <FONT color=#008080 size=2>XSModuleCompMpprLoader) and delegates the application of composite mappings (at the work item or presenter level) to the contained composite mappers; note that the module composite mapper class applies event publication and event subscription composite mappings to both work items and presenters (as specified in the configuration file) whereas workspace, UI extension site, and command composite mappings are applied to presenters only given the interpretation of the MVP pattern as realized in the POC framework implementation

    Sample screenshot

  • Composite Mapper Classes: the workhorses of the service, composite mapper classes apply composite mappings (at the work item or presenter level with the overloaded ApplyCompositeMappings method) based on the contained composites (if any) built from the module composite mapper XML configuration file

    Sample screenshot

    Several unique interfaces are provided on the composite mapper classes including:

    <FONT color=#008080 size=2>XSWorkspaceCompMppr
    .ShellWorkspaceCompMppr: workspace composite mapper for the shell that allows for...
    <FONT color=#008080 size=2>XSWorkspaceCompMppr.GetWorkspaceTopic: workspace topic access for view display by pre-defined workspace types

    The base
    <FONT color=#008080 size=2>XSPresenter.ShowView method displays its current view in the requested workspace as follows:

    <FONT color=#0000ff size=2>protected <FONT color=#0000ff size=2>void ShowView(<FONT color=#008080 size=2>XSWorkspaceType thisWorkspaceType)
    {
       
    <FONT color=#0000ff size=2>this.workItem.RootWorkItem.Workspaces[
           
    <FONT color=#008080 size=2>XSWorkspaceCompMppr.ShellWorkspaceCompMppr.GetWorkspaceTopic(
                thisWorkspaceType)].Show(
    <FONT color=#0000ff size=2>this.View);
    }

    Sample screenshot

    <FONT color=#008080 size=2>XSUIExtSiteCompMppr.GetUIElements: user interface element access for view management by the presenter (e.g., setting a menu item and toolbar item Checked property on command invocation); currently all UI elements are returned that match the topic parameter including either the UI element command, registration or parent topic property (obviously, this can be modified or extended to meet your needs)

    Sample screenshot

  • Composite Classes: composites are essentially persisted by (read-only) and built directly from the module composite mapper XML configuration file; static object creation methods (i.e., CreateInstance) are provided by each of the composite classes including some validation of XML configuration file input parameters passed from the <FONT color=#008080 size=2>XSModuleCompMpprLoader loader class

    Sample screenshot

Module Composite Mapper XML Configuration File Syntax and Examples (XSModuleCompMppr.xml)

The syntax of the module composite mapper XML configuration file is provided in detail below including example composite specifications. The module composite mapper service currently requires the following of the configuration file in order to function properly:

  • The configuration file and any associated image files must be set to compile as embedded resources in the container module project
  • The configuration file must be located and named per the following namespace hierarchy, i.e., folders and file name (assuming a project name of MyComponentModule)

    MyComponentModule.Services.XSModuleCompMppr.XSModuleCompMppr.xml

    The
    <FONT color=#008080 size=2>XSModuleCompMppr.CreateInstance method uses the following code in order to get a manifest resource stream using the <FONT color=#008080 size=2>IXSWorkItem parameter type (as it is expected to be in the assembly default namespace), standard module composite mapper service assembly extended namespace and filename (reference <FONT color=#008080 size=2>XSModuleCompMppr.AssyXSModuleCompMpprNS):

    mpprStream = thisWorkItem.GetType().Assembly.GetManifestResourceStream(
        thisWorkItem.GetType(),
    <FONT color=#008080 size=2>    XSModuleCompMppr.AssyXSModuleCompMpprNS);

XSModuleCompMppr.xml Syntax

<FONT color=#0000ff size=2>

<<FONT color=#800000 size=2>XtensibleSolutions<FONT color=#0000ff size=2> <FONT color=#ff0000 size=2>version<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>2.0"<FONT color=#0000ff size=2> <FONT color=#ff0000 size=2>language<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>XSModuleCompMppr"<FONT color=#0000ff size=2>>
    <!--<FONT color=#008000 size=2>Module composite mapper contains composite mappers: 
         * Workspace (optional; applies to shell presenter only)
         * UI extension site (optional)
         * Command (optional)
         * Event (optional) 
            NOTE: ALL WorkItems/Presenters publish generic events.<FONT color=#0000ff size=2>-->
    <<FONT color=#800000 size=2>Module_Composite_Mapper<FONT color=#0000ff size=2>>
      <!--<FONT color=#008000 size=2>Workspace composite mapper contains workspace composites:
            * Workspace type descriptor (optional; for readability only) and... 
            * Workspace type enumeration value (required)
            * Workspace topic (required)<FONT color=#0000ff size=2>-->
      <<FONT color=#800000 size=2>Workspace_Composite_Mapper<FONT color=#0000ff size=2>>
          <<FONT color=#800000 size=2>Workspace_Composite<FONT color=#0000ff size=2>
              <FONT color=#ff0000 size=2>XSWorkspaceType_Descriptor<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Foo"
<FONT color=#0000ff size=2><FONT color=#ff0000 size=2>              XSWorkspaceType_Enum<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>0"<FONT color=#0000ff size=2>
<FONT color=#ff0000 size=2>              Workspace_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>wks://XS/Shell/Foo"<FONT color=#0000ff size=2>/>
      <!--<FONT color=#008000 size=2>UI extension site composite mapper contains UI extension site composites: 
<FONT color=#0000ff>           * Parent topic (required)
           <FONT color=#008000 size=2><FONT color=#008000 size=2>* Insert priority (optional - defaults to 0.0; used to indicate an 
              insertion priority for positioning the UI element in relation to its sibling 
              items); if not populated, the null priority is assigned (0.0) and the default 
              CAB behavior is used for the requested insertion (appended as the last item); 
              if populated (with a float value), the indicated priority is assigned and 
              used for positioning the requested insertion where: 
              - the smaller the indicated magnitude, the higher its priority and the closer 
                the item will be to the top of the list if not the first (i.e., 1.0 is 
                considered "priority one", though the actual algorithm has no practical limit 
                on the lower bounds while also considering the special value of 0.0)
              - the higher the indicated magnitude, the lower its priority and the closer 
                the item will be to the bottom of the list if not the last (e.g., 99.0 is 
                lower priority than 1.0)
              - equivalent priorities result in the existing item taking precedence (i.e., the
                new item is inserted immediately after that which it is equal to in priority)
              - an assigned priority always takes precedence over those not assigned 
                that are appended as the last items (e.g., 99.0 is higher priority 
                than 0.0)
<FONT color=#0000ff>           * UI element Type (optional - defaults to "ToolStripMenuItem")
<FONT color=#0000ff>           * UI element properties (optional; a generic attribute with 
<FONT color=#0000ff>              property|value|property|value|... pairs used to configure 
<FONT color=#0000ff>              virtually any property on the created UI element); currently 
<FONT color=#0000ff>              supported property types include strings, booleans, and images...

<FONT color=#0000ff>              Examples: 

<FONT color=#0000ff>              "Text|&amp;File": sets the Text property on the UI element to "File" 
<FONT color=#0000ff>              with the "F" specified as the UI element mnemonic

<FONT color=#0000ff>              "Checked|true": sets the Checked property on the UI element to True

<FONT color=#0000ff>              "Image|MyImageFile.ico": sets the Image property on the UI element 
<FONT color=#0000ff>              from the image file as specified (e.g., toolbar icons); images must 
<FONT color=#0000ff>              be named per the property specification (e.g., MyImageFile.ico), 
<FONT color=#0000ff>              co-located alongside the composite mapper file in the XSModuleCompMppr 
<FONT color=#0000ff>              folder, and compiled as an embedded resource

<FONT color=#0000ff>           * Register topic (optional) and...
<FONT color=#0000ff>           * Register property (optional - defaults to "DropDownItems"; used to 
<FONT color=#0000ff>              indicate which property on the created UI element is registered as 
<FONT color=#0000ff>              an extension point)
<FONT color=#0000ff>           * Command topic (optional) and...
<FONT color=#0000ff>           * Command event name (optional - defaults to "Click")<FONT color=#0000ff size=2>-->
      <<FONT color=#800000 size=2>UIExtensionSite_Composite_Mapper<FONT color=#0000ff size=2>>
          <<FONT color=#800000 size=2>UIExtensionSite_Composite<FONT color=#0000ff size=2> 
              <FONT color=#ff0000 size=2>Parent_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ste://XS/Shell/Menu"
<FONT color=#ff0000>              Insert_Priority
<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>1.0"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              UIElement_Type<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ToolStripMenuItem"<FONT color=#0000ff size=2> 
<FONT color=#ff0000 size=2><FONT color=#0000ff>              UIElement_Properties<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Text|<FONT color=#ff0000 size=2>&amp;<FONT color=#0000ff size=2>File"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              Register_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ste://XS/Shell/Menu/File"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              Register_Property<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>DropDownItems"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/Shell/File_Click"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              Command_EventName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Click"<FONT color=#0000ff size=2>/>
      </<FONT color=#800000 size=2>UIExtensionSite_Composite_Mapper<FONT color=#0000ff size=2>>
      <!--<FONT color=#008000 size=2>Command composite mapper contains command composites: 
<FONT color=#0000ff>           * Command topic (required)
<FONT color=#0000ff>           * Command handler method name (required)<FONT color=#0000ff size=2>-->
      <<FONT color=#800000 size=2>Command_Composite_Mapper<FONT color=#0000ff size=2>>
          <<FONT color=#800000 size=2>Command_Composite<FONT color=#0000ff size=2> 
              <FONT color=#ff0000 size=2>Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/Shell/FileExit_Click"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              Command_HandlerName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>OnFileExit_Click"<FONT color=#0000ff size=2>/>
      </<FONT color=#800000 size=2>Command_Composite_Mapper<FONT color=#0000ff size=2>>
      <!--<FONT color=#008000 size=2>NOTE: ALL WorkItems/Presenters publish generic events.<FONT color=#0000ff size=2>-->
      <!--<FONT color=#008000 size=2>Event publication composite mapper contains event publication composites: 
<FONT color=#0000ff>           * Event topic (required)
<FONT color=#0000ff>           * Publication scope descriptor (optional; for readability only) and... 
<FONT color=#0000ff>           * Publication scope enumeration value (optional - defaults to 
<FONT color=#0000ff>             Global {0}); values include (see the CAB help for more info): 
<FONT color=#0000ff>                 - Global {0}
<FONT color=#0000ff>                 - WorkItem {1}
<FONT color=#0000ff>                 - Descendants {2} 
<FONT color=#0000ff>         * Publisher type descriptor (optional; for readability only) and... 
<FONT color=#0000ff>         * Publisher type enumeration value (optional - defaults to WorkItem {0}); 
<FONT color=#0000ff>            values include: 
<FONT color=#0000ff>                - WorkItem {0}
<FONT color=#0000ff>                - Presenter {1} 
<FONT color=#0000ff>         * Publication handler method name (required)<FONT color=#0000ff size=2>-->
      <<FONT color=#800000 size=2>EventPublication_Composite_Mapper<FONT color=#0000ff size=2>>
          <<FONT color=#800000 size=2>EventPublication_Composite<FONT color=#0000ff size=2> 
              <FONT color=#ff0000 size=2>Event_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>evt://XS/MyModule/MyEvent"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              PublicationScope_Descriptor<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Global"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              PublicationScope_Enum<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>0"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              XSEventPubSubType_Descriptor<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>WorkItem"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              XSEventPubSubType_Enum<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>0"<FONT color=#0000ff size=2> 
<FONT color=#ff0000 size=2><FONT color=#0000ff>              Publication_HandlerName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>BroadcastMyEvent"<FONT color=#0000ff size=2>/>
      </<FONT color=#800000 size=2>EventPublication_Composite_Mapper<FONT color=#0000ff size=2>>
      <!--<FONT color=#008000 size=2>Event subscription composite mapper contains event subscription composites: 
<FONT color=#0000ff>           * Event topic (required)
<FONT color=#0000ff>           * Subscriber type descriptor (optional; for readability only) and... 
<FONT color=#0000ff>           * Subscriber type enumeration value (optional - defaults to WorkItem {0}); 
<FONT color=#0000ff>              values include: 
<FONT color=#0000ff>                  - WorkItem {0}
<FONT color=#0000ff>                  - Presenter {1} 
<FONT color=#0000ff>           * Subscription method name (required)<FONT color=#0000ff size=2>-->
      <<FONT color=#800000 size=2>EventSubscription_Composite_Mapper<FONT color=#0000ff size=2>>
          <<FONT color=#800000 size=2>EventSubscription_Composite<FONT color=#0000ff size=2> 
              <FONT color=#ff0000 size=2>Event_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>evt://XS/MyModule/MyEvent"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              XSEventPubSubType_Descriptor<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>WorkItem"
<FONT color=#ff0000 size=2><FONT color=#0000ff>              XSEventPubSubType_Enum<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>0"<FONT color=#0000ff size=2> 
<FONT color=#ff0000 size=2><FONT color=#0000ff>              Subscription_MethodName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>OnReceiveMyEvent"<FONT color=#0000ff size=2>/>
      </<FONT color=#800000 size=2>EventSubscription_Composite_Mapper<FONT color=#0000ff size=2>>
    </<FONT color=#800000 size=2>Module_Composite_Mapper<FONT color=#0000ff size=2>>
</<FONT color=#800000 size=2>XtensibleSolutions<FONT color=#0000ff size=2>>

Module Composite Mapper Topic Formats

The following sub-sections provide guidance on standard module composite topic formats including examples. The examples use parameter strings and method attributes for context and clarity whereas the module composite mapper service actually alleviates the need for these decorations through use of the single-point of configuration module composite mapper file.

Workspace Topic Format

wks (workspace)
XS (Xtensible Solutions, Inc. or end-user company)
ModuleName (or Generic if application-wide)
Descriptor00/Descriptor01/...

(client-defined; workspace topic descriptor should use the relevant <FONT color=#008080 size=2>XSWorkspaceType name followed by a brief indication of the specific instance, such as WorkspaceTypeFooMain)

Examples

<FONT color=#0000ff size=2>

this.RootWorkItem.Workspaces.Add(
   
<FONT color=#0000ff size=2>this.Shell.GetWorkspace(<FONT color=#008080 size=2>XSWorkspaceType.WorkspaceTypeFoo), <FONT color=#800000 size=2>
    "wks://XS/Shell/WorkspaceTypeFooMain");

<FONT color=#008000 size=2><FONT color=#0000ff size=2>

this.RootWorkItem.Workspaces[<FONT color=#800000 size=2>"wks://XS/Shell/WorkspaceTypeFooMain"].Show(this.view);<FONT color=#008000 size=2>

UIExtensionSite Topic Format

ste (UIExtensionSite)
XS (Xtensible Solutions, Inc. or end-user company)
ModuleName (or Generic if application-wide)
Descriptor00/Descriptor01/...

(client-defined; site topic descriptors should use the path to the UIElement of interest)

Examples

<FONT color=#0000ff size=2>

this.RootWorkItem.UIExtensionSites.RegisterSite(
   
<FONT color=#800000 size=2>"ste://XS/Shell/Menu"
, <FONT color=#0000ff size=2>this.Shell.MainMenuStrip);

<FONT color=#0000ff size=2>this.RootWorkItem.UIExtensionSites.RegisterSite(
<FONT color=#800000 size=2>    "ste://XS/Shell/Menu/File", fileMenuItem);

Command Topic Format

cmd (command)
XS (Xtensible Solutions, Inc. or end-user company)
ModuleName (or Generic if application-wide)
Descriptor_Event

(client-defined; command topic descriptor should use a brief indication of the event followed by the actual event being handled, such as "FileExit_Click")

Command Invoker: Descriptor_Event (e.g., FileExit_Click)
Command Handler Method: OnDescriptor_Event (e.g., OnFileExit_Click)

Examples

Command Invoker

workItem.Commands[<FONT color=#800000 size=2>"cmd://XS/Shell/FileExit_Click"].AddInvoker(fileExitMenuItem, <FONT color=#800000 size=2>"Click");

Command Handler

[<FONT color=#008080 size=2>CommandHandler(<FONT color=#800000 size=2>"cmd://XS/Shell/FileExit_Click")]
<FONT color=#0000ff size=2>public void OnFileExit_Click(<FONT color=#0000ff size=2>object sender, <FONT color=#008080 size=2>EventArgs e) { myObject.MyMethod(); }

Event Topic Format

evt (event)
XS (Xtensible Solutions, Inc. or end-user company)
ModuleName (or Generic if application-wide)
Descriptor

(client-defined; event topic descriptor should use a brief indication of the event to be broadcast)

Event Publication Handler: BroadcastDescriptor (e.g., BroadcastFoo)
Event Subscription Method: OnReceiveDescriptor (e.g., OnReceiveFoo)

Examples

Event Publication

The publication handler itself...

[<FONT color=#008080 size=2>EventPublication(<FONT color=#800000 size=2>"evt://XS/Generic/Foo")]
<FONT color=#0000ff size=2>public <FONT color=#0000ff size=2>event <FONT color=#008080 size=2>EventHandler<<FONT color=#008080 size=2>DataEventArgs<<FONT color=#0000ff size=2>string>> BroadcastFoo;

Public method for invoking the publication handler from referring classes. While not required for events that should not be invoked except by the publishing class itself, if appropriate, provides an interface for referring classes that may also require invocation of the event, such as a view that may invoke an event defined on its owning presenter...

<FONT color=#0000ff size=2>

public <FONT color=#0000ff size=2>void DoBroadcastFoo(<FONT color=#0000ff size=2>object sender, <FONT color=#0000ff size=2>string thisMessage)
{
   
<FONT color=#0000ff size=2>this.BroadcastFoo(sender, <FONT color=#0000ff size=2>new <FONT color=#008080 size=2>DataEventArgs<<FONT color=#0000ff size=2>string>(thisMessage));
}

Event Subscription

[<FONT color=#008080 size=2>EventSubscription(<FONT color=#800000 size=2>"evt://XS/Generic/Foo")]
[
<FONT color=#008080 size=2>EventSubscription(<FONT color=#800000 size=2>"evt://XS/Generic/Bar")]
<FONT color=#0000ff size=2>public <FONT color=#0000ff size=2>void OnReceiveGeneric(<FONT color=#0000ff size=2>object sender, <FONT color=#008080 size=2>DataEventArgs<<FONT color=#0000ff size=2>string> e)
{
    myObject.MyMethod(e.Data);
}

Example Modules

XSShell

The XSShell application module provides core UI items such as a menu, toolbar and workspaces.

Sample screenshot

  • Module Composite Mapper File (<FONT color=#008080 size=2>XSModuleCompMppr.xml)

    Specifies a workspace topic for the Foo workspace type

    <FONT color=#0000ff size=2><<FONT color=#800000 size=2>Workspace_Composite<FONT color=#0000ff size=2> 
        <FONT color=#ff0000 size=2>XSWorkspaceType_Descriptor<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Foo"
       
    <FONT color=#ff0000 size=2>XSWorkspaceType_Enum<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>0"<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Workspace_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>wks://XS/Shell/Foo"<FONT color=#0000ff size=2>/>

    Specifies a user interface element on the standard file menu

    <FONT color=#0000ff size=2><<FONT color=#800000 size=2>UIExtensionSite_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Parent_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ste://XS/Shell/Menu"
    <FONT color=#0000ff>   
    <FONT color=#ff0000 size=2>Insert_Priority<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>1.0"
    <FONT color=#ff0000 size=2>    UIElement_Properties<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Text|<FONT color=#ff0000 size=2>&amp;<FONT color=#0000ff size=2>File"
       
    <FONT color=#ff0000 size=2>Register_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ste://XS/Shell/Menu/File"<FONT color=#0000ff size=2>/>

    <<FONT color=#800000 size=2>UIExtensionSite_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Parent_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ste://XS/Shell/Menu/File"
       
    <FONT color=#ff0000 size=2>UIElement_Properties<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Text|E<FONT color=#ff0000 size=2>&amp;<FONT color=#0000ff size=2>xit"
       
    <FONT color=#ff0000 size=2>Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/Shell/FileExit_Click"<FONT color=#0000ff size=2>/>

    Specifies a command handler for the UI element on the presenter

    <FONT color=#0000ff size=2><<FONT color=#800000 size=2>Command_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/Shell/FileExit_Click"
       
    <FONT color=#ff0000 size=2>Command_HandlerName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>OnFileExit_Click"<FONT color=#0000ff size=2>/>

In the POC framework, the XSShellApplication class overrides the AfterShellCreated method to register core UIExtensionSites in support of the module composite mapper service:

<FONT color=#0000ff size=2>this.RootWorkItem.UIExtensionSites.RegisterSite(
 
<FONT color=#800000 size=2>"ste://XS/Shell/Menu",
 
<FONT color=#008080 size=2>XSToolStripUIAdapterFactory.GetAdapter(<FONT color=#0000ff size=2>this.Shell.MainMenuStrip));
<FONT color=#0000ff size=2>this.RootWorkItem.UIExtensionSites.RegisterSite(
 
<FONT color=#800000 size=2>"ste://XS/Shell/Toolbar",
 
<FONT color=#008080 size=2>XSToolStripUIAdapterFactory.GetAdapter(<FONT color=#0000ff size=2>this.Shell.MainToolStrip));

MyServerModule

The MyServerModule provides a user interface on the shell that dynamically loads another module (MyClientModule) during application run-time.

Sample screenshot

  • Module Composite Mapper File (<FONT color=#008080 size=2>XSModuleCompMppr.xml)

    Specifies a user interface element on the standard tool menu

    <FONT color=#0000ff size=2><
    <FONT color=#800000 size=2>UIExtensionSite_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Parent_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ste://XS/Shell/Menu/Tools"
    <FONT color=#0000ff>   
    <FONT color=#ff0000 size=2>Insert_Priority<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>1.0"
        <FONT color=#ff0000 size=2>UIElement_Properties<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Text|<FONT color=#ff0000 size=2>&amp;<FONT color=#0000ff size=2>Load Client"
       
    <FONT color=#ff0000 size=2>Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/MyServerModule/ToolsLoadClientModule_Click"<FONT color=#0000ff size=2>/>

    Specifies a command handler for the UI element on the presenter

    <FONT color=#0000ff size=2><<FONT color=#800000 size=2>Command_Composite
        <FONT color=#ff0000 size=2>Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/MyServerModule/ToolsLoadClientModule_Click"
       
    <FONT color=#ff0000 size=2>Command_HandlerName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>OnToolsLoadClientModule_Click"<FONT color=#0000ff size=2>/>

    Specifies an event subscription to the MyClientModule ClientEvent

    <FONT color=#0000ff size=2><<FONT color=#800000 size=2>EventSubscription_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Event_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>evt://XS/MyClientModule/ClientEvent"
       
    <FONT color=#ff0000 size=2>Subscription_MethodName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>OnReceiveClientEvent"<FONT color=#0000ff size=2>/>

  • Presenter Class (<FONT color=#008080 size=2>MyServerPresenter): defines a command handler (OnToolsLoadClientModule_Click) that...

    Disables the user interface element on the standard tool menu
    Calls LoadClientModule on the work item

    Sample screenshot

  • View Class (<FONT color=#008080 size=2>XSView): no module-specific view class is defined (the base view implementation is instantiated on the presenter)
  • Work Item Class (<FONT color=#008080 size=2>MyServerWorkItem):

    Defines a method (LoadClientModule) that loads another module using the module loader service (MyClientModule with a hard-coded path)
    Defines a subscription method (OnReceiveClientEvent) that displays a message box on receiving the MyClientModule ClientEvent

    Sample screenshot

MyClientModule

The MyClientModule provides a user interface on the shell that allows the end-user to broadcast a module-defined event across the application, as well as show or hide its view.

Sample screenshot

  • Module Composite Mapper File (<FONT color=#008080 size=2>XSModuleCompMppr.xml)

    Specifies user interface elements on the standard view menu and toolbar (note the Checked and Image property settings)

    <FONT color=#0000ff size=2><
    <FONT color=#800000 size=2>UIExtensionSite_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Parent_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ste://XS/Shell/Menu/View"
    <FONT color=#0000ff>   
    <FONT color=#ff0000 size=2>Insert_Priority<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>1.0"
        <FONT color=#ff0000 size=2>UIElement_Properties<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Text|<FONT color=#ff0000 size=2>&amp;<FONT color=#0000ff size=2>Client|Checked|true"
       
    <FONT color=#ff0000 size=2>Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/MyClientModule/ViewMyClient_Click"<FONT color=#0000ff size=2>/>

    <<FONT color=#800000 size=2>UIExtensionSite_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Parent_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ste://XS/Shell/Toolbar"
    <FONT color=#0000ff>   
    <FONT color=#ff0000 size=2>Insert_Priority<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>1.0"
        <FONT color=#ff0000 size=2>UIElement_Type<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>ToolStripButton"
       
    <FONT color=#ff0000 size=2>UIElement_Properties<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>Image|LoadClientModule.ico|Checked|true"
       
    <FONT color=#ff0000 size=2>Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/MyClientModule/ViewMyClient_Click"<FONT color=#0000ff size=2>/>

    Specifies a command handler for the UI elements on the presenter

    <FONT color=#0000ff size=2><<FONT color=#800000 size=2>Command_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Command_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>cmd://XS/MyClientModule/ViewMyClient_Click"
       
    <FONT color=#ff0000 size=2>Command_HandlerName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>OnViewMyClient_Click"<FONT color=#0000ff size=2>/>

    Publishes a module-defined event with its publication handler on the presenter
    <FONT color=#0000ff size=2>

    <<FONT color=#800000 size=2>EventPublication_Composite<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Event_Topic<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>evt://XS/MyClientModule/ClientEvent"
       
    <FONT color=#ff0000 size=2>XSEventPubSubType_Enum<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>1"<FONT color=#0000ff size=2>
        <FONT color=#ff0000 size=2>Publication_HandlerName<FONT color=#0000ff size=2>="<FONT color=#0000ff size=2>BroadcastClientEvent"<FONT color=#0000ff size=2>/>

    <FONT color=#0000ff size=2>
  • Presenter Class (<FONT color=#008080 size=2>MyClientPresenter):

    On construction displays the view on the Bar (versus Foo) workspace
    Defines a publication handler (BroadcastClientEvent) that broadcasts the module-defined event
    Defines a command handler (OnViewMyClient_Click) that shows/hides its view

    Sample screenshot

    The OnViewMyClient_Click command handler sets the view visibility and uses the presenter
    <FONT color=#008080 size=2>UIExtSiteCompMppr.GetUIElements method to set the menu item and toolbar item Checked property on command invocation:

    <FONT color=#0000ff size=2>bool visible = (!(view.Visible));
    <FONT color=#0000ff size=2>foreach (<FONT color=#008080 size=2>ToolStripItem uiElement <FONT color=#0000ff size=2>in
            <FONT color=#0000ff size=2>this.UIExtSiteCompMppr.GetUIElements(((<FONT color=#008080 size=2>Command)sender).Name))
        uiElement.GetType().GetProperty(
    <FONT color=#800000 size=2>"Checked").SetValue(uiElement, visible, <FONT color=#0000ff size=2>null);
    view.Visible = visible;

  • View Class (<FONT color=#008080 size=2>MyClientView): defines a local user interface event (uiButtonBroadcastClientEvent_Click) that...

    Invokes the publication handler on the presenter (DoBroadcastClientEvent)

    Sample screenshot

Conclusion

The module composite mapper service provides a consistent, XML configurable, and single per-module persistence paradigm for dynamically building workspaces, UIElements, commands, and event publications/subscriptions within a CAB based application. Regardless of any up and coming composite builder architecture implemented by the Microsoft patterns & practices CAB team, the module composite mapper service provides a clear, concise and well-segregated framework for moving from the current (relatively undefined) approach into any production-oriented module composite development process. In fact, given the XML configuration oriented composite builder snippets available to date, albeit generally limited in scope compared to the module composite mapper service, one should be able to migrate relatively seamless from (or integrate across) the module composite mapper service and any successor approach.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Tom Polanski
Software Developer (Senior)
United States United States
Tom Polanski, Avionics Software Engineer
Abaco Systems

Abaco Systems delivers high performance rugged embedded computing solutions, based on industry standards and open architectures, to mission-critical applications in defense, aerospace and industry around the world.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
GeneralMy vote of 5 Pin
Heaven20205-Nov-10 9:55
memberHeaven20205-Nov-10 9:55 
GeneralCulture problem... Pin
ikharus12-Dec-06 12:03
memberikharus12-Dec-06 12:03 
Generalnested workitems Pin
thebts5-Dec-06 16:28
memberthebts5-Dec-06 16:28 
GeneralUser Interface Element Insert Priority Coming Soon! Pin
Tom Polanski21-Mar-06 6:08
memberTom Polanski21-Mar-06 6:08 
GeneralRe: User Interface Element Insert Priority Now Available! Pin
Tom Polanski30-Mar-06 17:04
memberTom Polanski30-Mar-06 17:04 
GeneralMyServerModule Dynamically Loads MyClientModule using Hardcoded Path Pin
Tom Polanski20-Mar-06 6:09
memberTom Polanski20-Mar-06 6:09 
GeneralBrilliant! Pin
gcadmes17-Mar-06 7:33
membergcadmes17-Mar-06 7:33 
GeneralAB's seem interesting Pin
Peter Hayward27-Feb-06 16:51
memberPeter Hayward27-Feb-06 16:51 
Yes these application blocks in the Enterprise library sure do look interesting. Your article looks good, hopefully I'll a chance to really look through it in more detail.

Peter Hayward

GeneralExcellent Pin
oykica27-Feb-06 14:19
memberoykica27-Feb-06 14:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.161208.2 | Last Updated 30 Mar 2006
Article Copyright 2006 by Tom Polanski
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid