In this article you'll look at another Smart Client technology. Specifically, you'll explore the Composite UI Application Block (CAB) from the Microsoft Patterns and Practices group. It allows you to build complex Windows Forms-based solutions using proven techniques that make it simple. This article won't have sample code as the articles normally do because it assumes you've downloaded the CAB file that contains full source code for your use.
Application Block Background
The CAB is designed to make it easier for you to build enterprise-ready Windows Forms applications. It is based on the Composite design pattern, which involves creating simple independent user interface parts and assembling them into a solution. A shell Windows Forms-based solution hosts the various parts that act as plug-ins. It allows you to build clients composed of independent yet cooperating modules. For those familiar with Windows SharePoint Services or SharePoint Server, it is similar in concept to SharePoint for Windows applications.
The power of CAB lies in the ability to separate development concerns to target resource expertise as well as to allow for a fluid application that is ready for change. By modularizing components and logic, a CAB application can handle modifications to individual pieces of the application with ease. It also enables out-of-the-box runtime UI customization capabilities based on user roles, which you will see later in this article.
The application block is a component built on the Microsoft .NET Framework 2.0. The full source code is available from the Microsoft Patterns and Practices site. It is available in Visual Basic .NET or C# formats.
There are two classes that are needed initially when building a CAB application. First, the ShellApplication is the class that encapsulates the entire application. Second, the WorkItem is a container for all of the classes that work together. A form will provide the real estate for the application. It holds what are known as workspace controls that will in turn contain the user interface parts known as SmartParts. There are several types of workspaces:
- WindowWorkspace: Show and hide controls inside a framed window.
- TabWorkspace: Show and hide controls and SmartParts inside a tab of pages.
- ZoneWorkspace: Create a tiled Workspace where you use splitter controls to create multiple column or row displays. It allows you to create columned and flexible displays similar to that of Microsoft Outlook.
- DeckWorkspace: Show and hide controls and SmartParts with no visible frame.
- MDIWorkspace: Show and hide controls and SmartParts in MDI child forms.
The following wireframe depicts an example of the ZoneWorkspace filled with various SmartParts.
Search Form SmartPart
Search Results SmartPart
Sharing Information with WorkItems
A CAB application can, and usually does, have multiple WorkItems, but it must have at least one (referred to as the root WorkItem). A WorkItem can be thought of as an implementation of one complete use case for the business logic of an application. Architected in this way, the application would have one WorkItem per use case that it defines. WorkItems hold state for the components contained within them. This allows the components to talk to each other and work together to accomplish the goal of the WorkItem. For example, components can customize (or extend) UIExtensionSites. An example of a UIExtensionSite is a MenuStrip. Because a UIExtensionSite is created at the shell level, the components within the WorkItems then can extend the MenuStrip with the additional items they need. This provides an easy way to manage shared components of the application's interface.
Building the Parts
SmartParts are the visual components of the application. They are hosted by a Workspace or SmartPartPlaceHolder control. You can create SmartParts by simply customizing a standard user control. They can be created in advance at design time or even created programmatically at runtime. They are designed to be pluggable and reusable within the same or other applications. To return to the SharePoint analogy mentioned earlier, you could think of these as being similar to WebParts.
Connecting the Parts
SmartParts are conceptually designed to be modular and independent of each other. This helps increase application stability and allows the application to be flexible. However, the parts must be able to communicate to cooperate. They can communicate by publishing and subscribing to events. Additionally, there is the state class, which is a dictionary of information that provides notification when items change. You should also be aware that CAB employs a "dependency injection" technique for allowing components to reference instances of other components in a highly fluid, pluggable system. The details of this topic, however, are beyond the scope of this article.