在Delphi中进行UI设计时,我们会在Form上放置许多的组件,当我们更改窗体的某些属性时,其上所有组件的相应属性都会随着发生改变,这是如何实现的呢?这里就使用到了Delphi VCL Framework中使用最多的一种设计模式 -- Notify模式。
Notify模式最经常发生的应用就是在容器类中的应用。由于容器类管理了许多子类对象,因此客户程序代码可能希望一次操作对所有容器类管理的子类对象进行特定的工作。在这种需求应用中就可以使用Notify模式,客户程序代码只需要传送事件给容器类,而容器类在接收到这个事件之后再逐一的通知它所管理的子类对象。
Delphi中所有组件都是从TComponent类继承而来的,只需要在这个类中实现通知模式,那么它所有的子类对象便都具备了这种模式能力。我们剖析一下Delphi是如何实现这个模式的。
首先打开TComponent所在的单元文件Classes.pas,查找到TComponent类的定义,我们可以看到如下代码(注意加粗的部分)
private
.......
FFreeNotifies:TList;
.......
procedureRemoveNotification(AComponent:TComponent);
.......
protected
.......
procedureNotification(AComponent:TComponent;
Operation:TOperation);virtual;
.......
public
constructorCreate(AOwner:TComponent);virtual;
destructorDestroy;override;
.......
procedureFreeNotification(AComponent:TComponent);
procedureRemoveFreeNotification(AComponent:TComponent);
.......
published
propertyName:TComponentNamereadFNamewriteSetNamestoredFalse;
propertyTag:LongintreadFTagwriteFTagdefault0;
end;
当一个组件被创建时,会通过FreeNotification方法将其添加到父组件的FFreeNotifies列表中,确保父组件发生变化时自己能够被通知到;同时父组件也被添加到自己的FFreeNotifies列表中,确保自己发生变化时能够通知到父组件。
begin
if(Owner=nil)or(AComponent.Owner<>Owner)then
begin
//Neveracquireareferencetoacomponentthatisbeingdeleted.
assert(not(csDestroyingin(ComponentState+AComponent.ComponentState)));
ifnotAssigned(FFreeNotifies)thenFFreeNotifies:=TList.Create;
ifFFreeNotifies.IndexOf(AComponent)<0then
begin
FFreeNotifies.Add(AComponent);
AComponent.FreeNotification(Self);
end;
end;
Include(FComponentState,csFreeNotification);
end;
与FreeNotification方法对应的有一个RemoveFreeNotification方法,此方法是将已经建立关联关系的组件从彼此的FFreeNotifies列表中删除,取消了由FreeNofifies建立的关联。
begin
RemoveNotification(AComponent);
AComponent.RemoveNotification(Self);
end;
当一个组件发生变化时,则会调用Notification方法通知FreeNofifies列表中所有的组件。
Operation:TOperation);
var
I:Integer;
begin
if(Operation=opRemove)and(AComponent<>nil)then
RemoveFreeNotification(AComponent);
ifFComponents<>nilthen
begin
I:=FComponents.Count-1;
whileI>=0do
begin
TComponent(FComponents[I]).Notification(AComponent,Operation);
Dec(I);
ifI>=FComponents.Countthen
I:=FComponents.Count-1;
end;
end;
end;
与Notification方法对应的亦有一个私有的RemoveNotification方法,此方法的作用是将与之关联的组件从FFreeNotifies列表中去除,如果没有与之关联的组件,则销毁FFreeNotifies列表。
begin
ifFFreeNotifies<>nilthen
begin
FFreeNotifies.Remove(AComponent);
ifFFreeNotifies.Count=0then
begin
FFreeNotifies.Free;
FFreeNotifies:=nil;
end;
end;
end;
小结一下
从TComponent类的定义代码可以看出Delphi只将FreeNotification和RemoveFreeNotification方法公开出来,是希望我们利用这两个方法在建立和取消组件间的关联;而将Notification方法定义为受保护的虚方法,则为我们提供了改写通知组件时执行附加操作的机会。
使用时机
- 在设计容器类时程序员想定义和外界一致的交互接口
- 需要对一群组件执行预定义好的特定工作
应用举例
在编写MIS软件时,会涉及到一些单据的填写,就以进货单为例。在一张进货单中会填写货品的单价、价格,我们希望在这两个字段的值发生变化时系统能够自动的计算出最新的总价。在这里,我们就可以借鉴Notify模式,将数量与单价加入到彼此的通知列表中,并编写通知处理方法如上面讲到的Notification方法。这样,无论单价还是数量发生变化都会触发通知事件,进而达到重新计算总价的目的。
个人拙见,还望各位斧正。
版权声明:本文为博主原创文章,未经博主允许不得转载。
相关推荐
在给出的文件信息中,我们可以了解到关于Delphi VCL(Visual Component Library,视觉组件库)的详细继承关系。VCL是Borland公司为Delphi开发的一套丰富的组件库,用于快速开发具有丰富图形用户界面的应用程序。 ...
安装 DevExpress for Delphi VCL 17.2.4 的过程非常简单,只需运行压缩包中的安装包,按照向导提示进行即可。"一键安装"意味着该版本已经集成了所有必要的组件和设置,用户无需进行复杂的配置,节省了开发者的宝贵...
在本压缩包中,开发者可以找到关于DevExpress Delphi VCL组件的各种技术细节、使用示例、API参考等,这些内容对于初学者和有经验的开发者来说都是非常宝贵的资源。 在Delphi的VCL框架中,开发者可以使用DevExpress...
在本主题中,我们关注的是如何在Delphi中利用VCL进行UDP通信。 标题"vcl.rar_Delphi VCL_delphi udp_vcl"暗示了我们将探讨如何在Delphi的VCL框架下实现基于UDP的网络通信。UDP(User Datagram Protocol)是一种无...
《Delphi VCL组件开发实例》是一份深入探讨Delphi集成开发环境中VCL(Visual Component Library)组件开发的专业文档。VCL是Delphi的核心部分,它提供了一整套丰富的用户界面控件和类库,使得开发者能够快速构建...
本教程将针对不熟悉DevExpress VCL安装过程的新手进行详细讲解,让新手能够顺利地在Delphi环境中安装并使用这一组件库。 首先,安装DevExpress VCL需要下载相应的安装包。在提供的文件列表中,“DevExpressVCL安装...
"神经网络 Delphi VCL"是一个专为Delphi设计的组件库,它允许开发人员在VCL(Visual Component Library)环境下轻松集成神经网络功能。 Delphi VCL是一个面向对象的库,用于创建Windows应用程序。它提供了丰富的...
Delphi VCL(Visual Component Library)架构是Delphi编程环境中核心的部分,它为开发者提供了丰富的图形用户界面(GUI)组件库。VCL是基于Object Pascal语言的,它使得开发高效、本地化的Windows应用程序变得非常...
在Delphi VCL(Visual Component Library)环境中,线程同步是一个关键的概念,特别是在多线程编程中。Synchronize方法是Delphi中用于在主线程和工作线程之间进行通信的关键工具,确保对用户界面(UI)的操作是安全...
在Delphi 11.3开发环境中,开发者经常会遇到需要在一个传统的VCL(Visual Component Library)窗体上嵌入FireMonkey (FMX)组件的情况。这通常发生在开发跨平台应用程序时,因为FMX提供了对多操作系统的支持。本知识...
通过Delphi VCL的强大可视化设计和事件驱动编程模式,可以极大地提高开发效率,同时保持代码的整洁和可维护性。 总的来说,"delphi VCL带源码,无限制经典mmtools,音频控件"是一个对于Delphi开发者特别是音频应用...
在Delphi编程环境中,NativeExcel是一个强大的库,它允许开发者直接在VCL(Visual Component Library)框架下处理Excel文件,无需依赖Microsoft Office组件。这个库的出现极大地简化了Delphi程序员在处理Excel数据时...
本文将深入探讨“NewNoteBook D6-XE7 Delphi VCL”这个NoteBook控件,它是专门为Delphi编程环境设计的。 首先,让我们了解“NewNoteBook”。标题中的“NewNoteBook D6-XE7”指的是该控件适用于Delphi从D6(Delphi 6...
ZipTV VCL组件使得开发者无需深入了解压缩算法的细节,就能轻松地在Delphi程序中添加创建、读取、修改和提取ZIP档案的功能。 【标签】中的关键词: 1. **delphi_vcl**:指的是Delphi的Visual Component Library,它...
FFVCL则是基于FFmpeg的VCL(Visual Component Library)组件,将这些功能集成到Delphi的开发环境中。开发者可以像使用其他Delphi组件一样,通过拖放和设置属性来实现复杂的音视频操作。 在提供的压缩包中,包含以下...
本文将重点介绍标题为“delphi 蓝牙VCL——BlueToothFramework”的资源,通过深入解析其核心组件和功能,帮助读者理解如何在Delphi中构建蓝牙应用程序。 BlueToothFramework是专门为Delphi开发者设计的一个蓝牙VCL...
在Delphi编程环境中,我们可以利用VCL(Visual Component Library)库来创建SNMP应用,实现对网络设备的监控和配置。 标题中的"SNMP.rar_HTTPSend_delphi_SNMP Delphi VCL_delphi HTTPSe_delphi h"暗示了这是一个...
DevExpress VCL for Delphi 是一套功能强大的可视化组件库,广泛应用于Delphi开发环境中的各种应用程序开发。该组件集提供了丰富的控件,包括数据网格、图表、报表等,可以极大提高开发效率,并使应用程序具有出色的...