类,对于一般参数配置过程,可以抽象出以下一些共性的必须执行的方法:
1、 显示界面时,初始化参数值。
2、 输入参数的有效性校验,如果无效,禁止点击确定按钮。
3、 执行参数的修改,如果成功,则关闭窗体,如果失败,则等待用户重新输入。
4、 点击默认设置时,恢复参数默认设置。
为了强制实现上面的四个业务逻辑,修改后的基类代码如下:
type TBaseOptionDlg = class(TForm)… public { Public declarations } constructor Create(AOwner:TComponent);override; procedure InitUI;virtual;abstract; function ParamsValid:Boolean;virtual;abstract; function UpdateParams:Boolean;virtual;abstract; procedure DefaultParams;virtual;abstract; end;…procedure TBaseOptionDlg.ActionOKUpdate(Sender: TObject);begin (Sender as TAction).Enabled:=ParamsValid;end; procedure TBaseOptionDlg.ActionOKExecute(Sender: TObject);begin if UpdateParams then begin ModalResult:=mrOk; end;end; procedure TBaseOptionDlg.ActionCancelExecute(Sender: TObject);begin ModalResult:=mrCancel;end;…constructor TBaseOptionDlg.Create(AOwner: TComponent);begin inherited; initUI;end; procedure TBaseOptionDlg.ActionDefaultExecute(Sender: TObject);begin DefaultParams;end; end.
为了实现前面定义的业务逻辑,我们在窗体构造方法中调用InitUI过程来初始化界面,而在Action的OnUpdate事件中不停调用ParamsValid函数判断当前输入的参数是否有效,如果有效,则允许点击确定按钮。点击确定按钮后,会调用UpdateParams方法来更新参数,如果更新成功,则关闭界面,否则等待用户重新输入。最后,在用户点击恢复默认参数值按钮时,调用DefaultParams方法来完成。要注意的是,基类中的initUI,ParamValid,UpdateParams和DefaultParams过程都被定义为纯虚的抽象方法。这是因为对于基类来说,由于没有具体的参数输入界面元素,实现这些方法是没有意义的,只有到了具体的参数配置界面,才需要实现这些方法,同时定义为Abstract抽象方法可以强迫派生类必须实现这几个方法来完成业务逻辑,否则编译后无法正确运行。
下面是TDBOptionDlg实现的示意性代码:
procedure TDBOptionDlg.DefaultParams;begin edtDB.Text:='c:\hubdog.db';end; procedure TDBOptionDlg.InitUI;begin edtDB.Text:='c:\hubdog.db';end; function TDBOptionDlg.ParamsValid: Boolean;begin Result:=trim(edtDB.Text)<>'';end; function TDBOptionDlg.UpdateParams: Boolean;begin Result:=True;end; end.
另外,窗体继承不支持窗口嵌套,也就是不支持窗口的组合复用,因此为了扩充窗口的功能,无形中鼓励人们使用继承机制,而不是组合机制。这加深了窗口之间的偶合度,不利于灵活性
和扩展性。
窗体继承还有一个很大的问题就是它只支持窗口级别的组件复用,但是更多的时候,我们想要的只是粒度更小的界面中某一部分显示区域或者组件级别的复用。Borland也考虑到了这个问题,因此在Delphi4中给出了Component
Template的解决方案。
组件模版模板
组件模版模板技术相当简单,比如下图所示意的双列表框组合界面是很
常用的一类界面,可以用来从一个
列表框向另一个列表框移动对象。
那么我们就可以选择列表框和按钮,然后执行 Component | Create Component
Template...命令来创建组件模版模板,示意图如下:
设定组件模版模板名称为TDualListBox,并将其作为一个组件放到Templates组件面板上,组件面板除了能保存各个组件的属性外,还可以保存相关组件的事件代码。还有一点限制是它不能将窗体设定为组件模版模板。
生成好的组件模版