More Detail On Workspaces And SmartParts (Introduction To The CAB/SCSF Part 16)

Introduction

Part 15 of this series of articles explained SmartParts in the CAB, and gave a very brief introduction to Workspaces. This article will continue with the same topics. In particular we will look in more detail at Workspaces.

Workspaces Recap

Part 15 explained the SmartParts can be most easily thought of as user controls or views in a composite application block application.

Part 15 also explained that Workspaces are just controls that allow other controls (SmartParts) to be laid out within them, and differ from other container controls in that they interact with other objects in the CAB in a predefined way. In particular there is a Workspaces collection on any WorkItem, and they have a Show method that shows a SmartPart.

User Interface Design for Business Applications

In an earlier blog posting on user interface design I discussed some of the possible user interface designs for applications that have to display multiple different screens of data. A common design for these applications is to have a tabbed client area for the screens, together with a tree-based window manager of some kind. An alternative is an Outlook-style interface, again possibly with a tree window manager, but dispensing with tabs at the top of the screen. Clearly both of these designs are very similar: we click on a tab or double-click in a tree and our screen gets displayed in a predefined part of the screen.

One thing to notice with both of these designs is that after we have displayed a client screen for the first time we won’t usually close it again. When other screens are displayed our first screen will stay in memory. It will retain the state it was displaying the last time the user interacted with it. When the user requests to see the screen again it will just be brought to the front.

So we have a collection of objects (our screens) with persistent state whilst the application is running. We may create all of these screens at start-up. However more usually we’ll create a screen the first time the user requests it, and then redisplay it the second time it is requested (a sort of lazy initialization). Note that at any given time many of the screens in the collection may not actually be displayed at all.

Building User Interfaces for Business Applications

Of course it is easy enough to create an application of this kind using Windows Forms standard controls. However, there’s some infrastructure code that we are going to have to write. We need:

  • some means of caching our screens collection
  • a way of allowing new screens to be added to the screens collection
  • a method of displaying a screen when it is requested for the first time
  • a method of redisplaying the appropriate screen in response to the appropriate request

We’ll also want to make sure we control the scope of our screens carefully so that they can’t be accessed from anywhere in the code. As we all know, global singletons (or global variables of any kind) are a bad thing.

The good news is that Workspaces and SmartParts do all this for us. What’s more they do it in a very simple way.

Workspaces – the IWorkspace Interface

All Workspaces implement the IWorkspace interface. This is the interface we are meant to use to interact with our Workspaces: usually we don’t need any more functionality than this interface provides as we shall see.

The IWorkspace interface has a number of useful methods. In general these behave as explained below, although each type of Workspace is free to implement them in its own way:

void Show(object smartPart)

When this method is called, if the SmartPart passed as a parameter has not previously been shown in this Workspace it will be loaded and then activated. If it has already been shown and not been closed (i.e. if it is in the Workspace’s SmartParts collection) it will just be activated. Usually ‘activated’ means brought to the front and made into the ActiveSmartPart.

void Activate(object smartPart)

If the object is in the Workspace’s SmartParts collection it will be activated as described above. If it’s not in that collection then an ArgumentException will be thrown.

void Hide(object smartPart)

Hides the SmartPart (sends it to the back usually), but leaves it in the Workspace’s SmartParts collection. The next control in the Workspace will usually be activated (made into the ActiveSmartPart). What ‘next’ means here varies by Workspace.

void Close(object smartPart)

Hides the SmartPart and also removes it from the SmartParts collection. The next control in the Workspace will usually be activated.

IWorkspace also has a property ActiveSmartPart, which returns the active SmartPart if there is one. As discussed in part 15 Workspaces have a SmartParts collection, and the IWorkspace interface has a SmartParts property that lets us access this (it returns a ReadOnlyCollection<object>).

IWorkspace also has events SmartPartActivated and SmartPartClosing. You can probably guess when these get fired.

There are also some methods to deal with SmartPartInfo on IWorkspace. I’ll discuss SmartPartInfo below.

Workspaces – Aside on how the Supporting Classes Work

The core functionality of IWorkspace is encapsulated in a class called, appropriately, Workspace. This is an abstract base class that all Workspaces are expected to inherit from. It implements IWorkspace so the individual Workspace classes don’t have to (since they inherit the interface from Workspace).

The base class gives basic implementations of the members of IWorkspace, and also handles things like caching the active smart part, tracking the SmartParts collection, and raising the right events at the right time.
Whilst the way the supporting classes work is quite interesting, you don’t need to know it in any detail to use the Workspace classes. The exception to this is if you want to write your own custom Workspace class, in which case you will need to get to grips with them in more detail. Writing your own custom Workspaces is beyond the scope of these articles for now.

Further Aside on Multiple Inheritance in C#

The Workspace classes also demonstrate a method of achieving a kind of multiple inheritance in C#. This is done by composition, using a class called WorkspaceComposer and an interface called IComposableWorkspace. It’s needed because certain Workspace classes (e.g. TabWorkspace) already inherit a Control class to give their basic functionality (in the case of TabWorkspace this is TabControl). As we know, in .NET a class can’t directly inherit more than one other class.

It is not my intention in these articles to actually discuss the underlying code in the Composite Application Block in any detail. The aim of these articles is to let you use the CAB as a black box component. But the WorkspaceComposer is particularly interesting since it shows us a pattern for achieving multiple inheritance (albeit messily) in C#. If you are interested the code is in the Microsoft.Practice.CompositeUI.SmartParts namespace in the Microsoft.Practices.CompositeUI component.

SmartPartInfo

As we have seen the normal Show method on the IWorkspace interface only lets you pass the SmartPart you want to show as a parameter. There may be other information that the CAB framework will need to know to show your SmartPart correctly. For example, in a TabWorkspace you need to provide the text for a new tab somehow. In a ZoneWorkspace you need to tell the CAB which particular zone the SmartPart will be displayed in.

This problem is solved by passing an additional object to the Show method:

void Show(object smartPart, ISmartPartInfo smartPartInfo)

This additional object implements the interface ISmartPartInfo, which has Title and Description properties. It’s the Title property that’s used to set the tab page title in the TabWorkspace.

The smartPartInfo object can contain any additional information we require. For example, for ZoneWorkspaces it contains the name of the zone in which the SmartPart will be displayed.

The IWorkspace interface also has a method to directly apply the information in a SmartPartInfo object to a SmartPart that has already been displayed:

void ApplySmartPartInfo(object smartPart, ISmartPartInfo smartPartInfo)

In a ZoneWorkspace this can be used to change the zone where a SmartPart is shown in, for example. The next article in this series will give some examples of this.

Conclusion

This article has discussed some of the theory behind Workspaces, and shown the basic interfaces. Part 17 in this series of articles will discuss the various types of Workspace that are available in the CAB, and give some code examples of how to use them.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前台: (1)注册登录模块:按照学校的相关规定进行注册和登录。 (2)招聘信息查看:高校毕业生们可以网站首页上查看所有的招聘信息,除此之外还可以输入公司名称或岗位名称进行搜索。 (3)用人单位模块:此模块为宣传用人单位的主要功能模块,具体包括用人单位简介、岗位需求及职责及公司介绍等功能。 (4)就业指导:学生朋友们在就业前可以通过此模块获取指导。 (5)新闻信息:为了让用户们可以了解到最新的新闻动态,本系统可以通过新闻信息查看功能阅读近期的新闻动态。 (6)在线论坛:毕业季的同学们可以通过此模块相互交流。 后台: (1)系统用户管理模块:可以查看系统内的管理员信息并进行维护。 (2)学生管理模块:通过此功能可以添加学生用户,还可以对学生信息进行修改和删除。 (3)用人单位管理模块:管理员用户通过此模块可以管理用人单位的信息,还可以对用人单位信息进行查看和维护。 (4)招聘管理模块:管理员通过此功能发布和维护系统内的照片信息。 (5)就业指导管理模块:通过此模块可以编辑和发布就业指导信息,从而更好的帮助就业季的同学们。 (6)论坛管理:通过论坛管理可以查看论坛中的主题帖及里面的回复信息,除此之外还可以对论坛中的信息进行维护和管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值