您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 工作范文 > 第十九章Delphi自定义部件开发(二)
19.2.2Delphi部件编程19.2.2.1创建属性属性(Property)是部件中最特殊的部分,主要因为部件用户在设计时可以看见和操作它们,并且在交互过程中能立即得到返回结果。属性也很重要,因为如果将它们设计好后,将使用户更容易地使用,自己维护起来也很容易。为了使你在部件中更好地使用属性,本部分将介绍下列内容:●为什么要创建属性●属性的种类●公布(publishing)继承的属性●定义部件属性●编写属性编辑器1.为什么要创建属性属性提供非常重要的好处,最明显的好处是属性在设计时能出现在ObjectInspector窗口中,这将简化编程工作,因为你只需读用户所赋的值,而不要处理构造对象的参数。从部件使用者的观点看,属性象变量。用户可以给属性赋值或读值,就好象属性是对象的域。从部件编写者的观点看属性比对象的域有更强的功能;⑴用户可以在设计时设置属性这是非常重要的,因为不象方法,只能在运行时访问。属性使用户在运行程序之前就能定制部件,通常你的部件不应包含很多的方法,它们的功能可以通过属性来实现。⑵属性能隐藏详细的实现细节⑶属性能引起简单地赋值之外的响应,如触发事件⑷用于属性的实现方法可以是虚拟方法,这样看似简单的属性在不同的部件中,将实现不同的功能。2.属性的类型属性可以是函数能返回的任何类型,因为属性的实现可以使用函数。所有的Pascal类型,兼容性规则都适用属性。为属性选择类型的最重要的方面是不同的类型出现在ObjectInspector窗口中的方式不同。ObjectInspector将按不同的类型决定其出现的方式。你也能在注册部件时描述不同的属性编辑器。下表列出属性出现在ObjectInspector窗口中的方式表19.3属性出现在ObjectInspector窗口中的方式━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━属性类型处理方式───────────────────────────────────────简单类型Numeric、Character和String属性出现在ObjectInspector中,用户可以直接编辑枚举类型枚举类型的属性显示值的方式定义在代码中。选择时将出现下拉式列表框,显示所有的可能取值。集合类型集合类型出现在ObjectInspector窗口中时正如一个集合,展开后,用户通过将集合元素设为True或False来选择。对象类型作为对象的属性本身有属性编辑器,如果对象有自己的published属性,用户在ObjectInspector中通过展开对象属性列,可以独立编辑它们,对象类型的属性必须从TPersistent继承。数组类型数组属性必须有它们自己的属性编辑器,ObjectInspector没有内嵌对数组属性编辑的支持。━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━3.公布继承的属性所有部件都从祖先类型继承属性。当你从已有部件继承时,新部件将继承祖先类型的所有属性。如果你继承的是抽象类,则继承的属性是protected或public,但不是published。如想使用户访问protected或public属性,可以将该属性重定义为published。如果你使用TWinControl继承,它继承了Ctl3D属性,但是protected的,因此用户在设计和运行时不能访问Ctl3D,通过在新部件中将Ctl3D重声明为published,就改变了Ctl3D的访问级别。下面的代码演示如何将Ctl3D声明为published,使之在设计时可被访问。typeTSampleComponent=class(TWinControl)publishedpropertyCtl3D;end;4.定义部件属性⑴属性的声明声明部件的属性,你要描述:●属性名●属性的类型●读和设置属性值的方法至少,部件属性应当定义在部件对象声明的public部分,这样可以在运行时很方便地从外部访问;为了能在设计时编辑属性,应当将属性在published部分声明,这样属性能自动显示在ObjectInspector窗口中。下面是典型的属性声明:typeTYourComponent=class(TComponent)…privateFCount:Integer{内部存储域}functionGetCount:Integer;{读方法}procedureSetCount(ACount:Integer);{写方法}pubilicpropertyCount:IntegerreadGetCountwriteSetCount;end;⑵内部数据存储关于如何存储属性的数据值,Delphi没有特别的规定,通常Delphi部件遵循下列规定:●属性数据存储在对象的数据域处●属性对象域的标识符以F开头,例如定义在TControl中的属性FWidth●属性数据的对象域应声明在private部分后代部件只应使用继承的属性自身,而不能直接访问内部的数据存储。⑶直接访问使属性数据可用的最简单的办法是直接访问。属性声明的read和write部分描述了怎样不通过调用访问方法来给内部数据域赋值。但一般都用read进行直接访问,而用write进行方法访问,以改变部件的状态。下面的部件声明演示了怎样在属性定义的read和write部分都采用直接访问:typeTYourComponent=class(TComponent)…private{内部存储是私有}FReadOnly:Boolean;{声明保存属性值的域}published{使属性在设计时可用}propertyReadOnly:BooleanreadFReadOnlywriteFReadOnly;end;⑷访问方法属性的声明语法允许属性声明的read和write部分用访问方法取代对象私有数据域。不管属性是如何实现它的read和write部分,方法实现应当是private,后代部件只能使用继承的属性访问。①读方法属性的读方法是不带参数的函数,并且返回同属性相同类型的值。通常读函数的名字是“Get”后加属性名,例如,属性Count的读方法是GetCount。不带参数的唯一例外是数组属性。如果你不定义read方法,则属性是只写的。②写方法属性的写方法总是只带一个参数的过程。参数可以是引用或值。通常过程名是Set加属性名。例如,属性Count的写方法名是SetCount。参数的值采用设置属性的新值,因此,写方法需要执行在内部存储数据中写的操作。如果没有声明写方法,那么属性是只读的。通常在设置新值前要检测新值是否与当前值不同。下面是一个简单的整数属性Count的写方法:procedureTMyComponent.SetCount(value:Integer);beginifvalueFCountthenbeginFCount:=Value;update;end;end;⑸缺省属性值当声明一个属性,能有选择地声明属性的缺省值。部件属性的缺省值是部件构造方法中的属性值集。例如,当从ComponentPalette选择某部件置于窗体中时,Delphi通过调用部件构造方法创建部件,并决定部件属性初始值。Delphi使用声明缺省值决定是否将属性值存在DFM文件中。如果不描述缺省值,Delphi将总是保存该属性值。声明缺省值的方法是在属性声明后加default指令,再跟缺省值。当重声明一个属性时,能够描述没有缺省值的属性。如果继承的属性已有一个,则设立没有缺省值的属性的方法是在属性声明后加nodefault指令。如果是第一次声明属性,则没有必要加nodefault指令,因为没有default指令即表示如此。下例是名为IsTrue的布尔类型属性设置缺省值True的过程:typeTSampleComponent=class(TComponent)privateFIsaTrue:Boolean;pubilicconstructorCreate(AOwner:TComponent);Overvide;publishedpropertyIstrue:BooleanreadFIsTruewriteFIsTruedefaultTrue;end;constructorTSampleComponent.Create(AOwner:TComponent);begininheritedCreate(Aowner);Fistvue:=True;{设置缺省值}end;5.编写属性编辑器ObjectInspector提供所有类型属性的缺省编辑器,Delphi也支持通过编写和注册属性编辑器的方法为属性设计自己的编辑器。可以注册专门为自定义部件的属性设计的编辑器,也可设计用于所有某类型的属性。编写属性编辑器需要下列五个步骤:●继承一个属性编辑器对象●将属性作为文本编辑●将属性作为整体编辑●描述编辑器属性●注册属性编辑器⑴继承属性编辑器对象DsgnIntf库单元中定义了几种属性编辑器。它们都是从TPropertyEditor继承而来。当创建属性编辑器时,可以直接从TPropertyEditor中继承或从表中的任一属性编辑器中继承。表19.4属性编辑器的类型━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━类型编辑的属性─────────────────────────────────────TOrdinalProperty所有有序的属性(整数、字符、枚举)TIntegerProperty所有整型,包括子界类型TCharProperty字符类型或字符子集TEnumProperty任何枚举类型TFloatProperty所有浮点数TStringProperty字符串,包括定长的字符串TSetElementProperty集合中的独立元素TSetElementProperty所有的集合,并不是直接编辑集合类型,而是展开成一列集合元素属性TClassProperty对象,显示对象名,并允许对象属性的展开TMethodPropevty方法指针,主要指事件TComponentProperty相同窗体中的部件,用户不能编辑部件的属性,但能指向兼容的部件TColorProperty部件颜色,显示颜色常量,否则显示十六进制数TFontNameProperty字体名称TFontProperty字体,允许展开字体的属性或弹出字体对话框━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━下面是TFloatPropertyEditor的定义:typeTFloatProperty=Class(TPropertyEditor)publicfunctionAllEqual:Boolean;override;functionGetValue:String;override;procedureSetValue(ConstValue:string);override;end;⑵象文本一样编辑属性所有的属性都需要将它们的值在ObjectInspector窗口中以文本的方式显示。属性编辑器对象提供了文本表现和实际值之间转换的虚方法。这些虚方法是GetValue和SetValue,你的属性编辑器也能继承了一系列的方法用于读和写不同类型的值。见下表:表19.5读写属性值的方法━━━━━━━━━━━━━━━━━━━━━━━━━━属性类型Get方法Set方法──────────────────────────浮点数GetFloatValueSetFloatVallue方法指针GetMethodValueSetMehodValue有序类型GetOrdValueSetOrdValue字符串GetStrValueSetStrValue━━━━━━━━━━━━━━━━━━━━━━━━━━当覆盖GetValue方法时,调用一个Get方法;当覆盖SetValue方法时调用一个Set方法。属性编辑器的GetValue方法返回一个字符串以表现当前属性值。缺省情况下GetValue返回unknown。属性编辑器的SetVal
本文标题:第十九章Delphi自定义部件开发(二)
链接地址:https://www.777doc.com/doc-2163049 .html