Why is Common.ControlledWorkItem sealed?

Topics: CAB & Smart Client Software Factory
Feb 4, 2006 at 7:42 AM
originally posted by: PJackson

Our application would call for modules and different workitems within modules to modify the UI when they activate/deactivate (changing the primary view, adding/removing menu items, etc.).

In the original CAB release, we were planning to have the workitem do this in OnActivated / OnDeactivated.

In the SCBAT reference application, it appears that we would use a ControlledWorkItem in conjunction with a WorkItemController -- but ControlledWorkItem is sealed and WorkItemController does not have similiar methods?

Is ControlledWorkItem sealed by design? And if so, shouldn't it be passing its events to the controller?
Feb 4, 2006 at 1:14 PM
originally posted by: Delphinus


I think ControlledWorkItem is sealed by design, and you don't need to extend it and override the OnActivated / OnDeactivated methods. The WorkItemController have access to the WorkItem, so all you need is to subscribe the WorkItem.Activated and WorkItem.Deactivated (for example on the WorkItemController.Run() method).


Feb 6, 2006 at 11:26 AM
originally posted by: BradWilsonMSFT

It is sealed by design. Our intention would be to extend WorkItemController to support any events from the WorkItem that we need. At the moment we don't need any of those, so none of them have been extended.

Bear in mind that SC-BAT is not a part of CAB. It is not our intent with the first RI to make ControlledWorkItem fully featured as though it were a part of CAB; it contains only what is necessary for our project, for the purposes of illustration.
Feb 6, 2006 at 4:04 PM
originally posted by: PJackson

What does this model then do to WorkItemExtension? Is it the intent that controlled workitems cannot be extended via this method?

Or am I missing something about WorkItemExtension (entirely possible)? I was under the impression that a WorkItemExtension would be associated with given Type(s) of workitems?
Feb 7, 2006 at 12:24 PM
originally posted by: BradWilsonMSFT

This has no impact on WorkItem extensions. If you wanted to extend a controlled work item, for example the one that is based on ModuleController in the RI-1 module, you would extend the type ControlledWorkItem<ModuleController>.
Feb 7, 2006 at 1:40 PM
originally posted by: PJackson

Very cool. Thanks!
Aug 15, 2008 at 6:58 AM
But what if you wanted to extend a workitem which is in another module and did not want to bind directly against it but against an interface implemented by the base workitem? I believe extending workitems dont make sense if they are in the same module as the original workitem and if they are in a separate module I would have to directly reference the base module which I believe is not sensible!
Aug 18, 2008 at 9:55 PM

To make it work, I patched (Version 4 RTM code) WorkItemExtensionService.GetRegisteredExtensions(Type)


                         �                     return extensions.FindAllValuesByKey(

                                 �                             delegate(Type key)

      �                                                        {

                                             �                                return key.IsAssignableFrom(workItemType);

                                                �              });


 �                                             var types = new List(extensions.FindAllValuesByKey(

                                                     �         key => key.IsAssignableFrom(workItemType)));

                                        �      //TW: new, scan base types of generic argument (ie in ControlledWorkItem)

                   �                           var wiParamTypes = workItemType.GetGenericArguments();

                                               if (wiParamTypes == null || wiParamTypes.Length == 0) return types;

                                        �      foreach (var typePair in extensions) {

                   �                                           var paramTypes = typePair.Key.GetGenericArguments();

                                �                              if (paramTypes == null || paramTypes.Length == 0) continue;

             �                                                 foreach (var paramType in paramTypes) {

    �                                                        �                if (paramType.IsAssignableFrom(wiParamTypes[0]))

    �                                                        �                                types.AddRange(typePair.Value);

                                                      �        }

                                    �          }

                                  �            return types;

Maybe someone can add this in a future build.

Regards, Tilli