Writing Property Editors 编写属性编辑器

 

When you select a component in the designer its properties are displayed in the object inspector. You can create your own editor for any property. The “Font” property, for example, has an editor : if this property is selected a '...' button appears to the right of the line; open the standard "font properties" dialogue by clicking this button. Another example is the “Color” property. It opens the standard colors and color specimens names in a drop-down list.

“TfrxPropertyEditor” is the base class for all property editors and is declared in the “frxDsgnIntf” unit:

"TfrxPropertyEditor"是属性编辑器的基类,声明在frxDsgnIntf单元:

TfrxPropertyEditor = class(TObject)

protected

procedure GetStrProc(const s: String);

function GetFloatValue: Extended;

function GetOrdValue: Integer;

function GetStrValue: String;

function GetVarValue: Variant;

procedure SetFloatValue(Value: Extended);

procedure SetOrdValue(Value: Integer);

procedure SetStrValue(const Value: String);

procedure SetVarValue(Value: Variant);

public

constructor Create(Designer: TfrxCustomDesigner); virtual;

destructor Destroy; override;

function Edit: Boolean; virtual;

function GetAttributes: TfrxPropertyAttributes; virtual;

function GetExtraLBSize: Integer; virtual;

function GetValue: String; virtual;

procedure GetValues; virtual;

procedure SetValue(const Value: String); virtual;

procedure OnDrawLBItem(Control: TWinControl; Index: Integer;ARect: TRect; State: TOwnerDrawState); virtual;

procedure OnDrawItem(Canvas: TCanvas; ARect: TRect); virtual;

property Component: TPersistent readonly;

property frComponent: TfrxComponent readonly;

property Designer: TfrxCustomDesigner readonly;

property ItemHeight: Integer;

property PropInfo: PPropInfo readonly;

property Value: String;

property Values: TStrings readonly;

end;

You also can inherit from any of the following classes, which provide some basic functionality for working with a property of the corresponding type:

你还可以从下列任何类中继承,该类提供一些基本功能,用于与相应类型的属性工作:

TfrxIntegerProperty = class(TfrxPropertyEditor)

TfrxFloatProperty = class(TfrxPropertyEditor)

TfrxCharProperty = class(TfrxPropertyEditor)

TfrxStringProperty = class(TfrxPropertyEditor)

TfrxEnumProperty = class(TfrxPropertyEditor)

TfrxClassProperty = class(TfrxPropertyEditor)

TfrxComponentProperty = class(TfrxPropertyEditor)

 

Several properties are defined in the TfrxPropertyEditor class:

几个属性是在TfrxPropertyEditor 中类定义:

- Component    link to parent component (not to property itself!) to which the given property belongs

- frComponent    the same, but cast to TfrxComponent type (convenient in some cases)

- Designer    link to the report designer

- ItemHeight    item height, in which property is displayed; it can be useful in OnDrawXXX

- PropInfo    link to PPropInfo structure, which contains information about the edited property

- Value    property value displayed as a string  // 属性的值显示为字符串

- Values    list of values; this property is to be filled by the “GetValue” method, if the “paValueList” attribute is defined (see below)

 

The following are system methods. They can be used to get or set the edited property value.

定义的相关方法:

function GetFloatValue: Extended;

function GetOrdValue: Integer;

function GetStrValue: String;

function GetVarValue: Variant;

procedure SetFloatValue(Value: Extended);

procedure SetOrdValue(Value: Integer);

procedure SetStrValue(const Value: String);

procedure SetVarValue(Value: Variant);

 

You should use the methods appropriate to the property type. So, use “GetOrdValue” and “SetOrdValue” methods if the property is of “Integer” type, etc.. These methods are also used for working with properties of “TObject" type, since these properties contain a 32-bit object address. In these cases, just use a cast like: MyFont := TFont(GetOrdValue).

你应该使用属性类型相适应的方法。这些方法也适用于属性是“TObject”类型,因为这些属性包含一个32位对象地址,比如MyFont := TFont(GetOrdValue),用类型转换进行处理。

To create your own editor, inherit from the base class and override some methods declared in the public section (which methods is dependent on the property type and functionality you wish to implement). One of the methods that will need to be overridden is “GetAttributes” which returns a set of property attributes. Attributes are defined in the following way:

编写自己的属性编辑器,要重写GetAttributes方法。返回一组属性值。属性值被定义如下方式:

TfrxPropertyAttribute = (paValueList, paSortList, paDialog, paMultiSelect,paSubProperties, paReadOnly, paOwnerDraw);

TfrxPropertyAttributes = set of TfrxPropertyAttribute;

Attribute meanings are:

属性值的意思:

- paValueList
property represents a drop-down list of values (for example the “Color” property);
if present then the “GetValues” method should be overridden

属性值是下拉列表形式,重写GetValues方法。

- paSortList
sorts list values; it is used together with paValueList

分类列表值;它与paValueList一起使用

- paDialog
property has an editor; if present a '...' button is displayed to the right of the line; Edit method is called by clicking on it

属性是个编辑器,调用Edit 方法。

- paMultiSelect
allows more than one object to be selected at the same time; some properties (such as “Name”, etc) do not have this attribute

- paSubProperties
property is object of TPersistent type and has its own properties, which should also be displayed (for example the “Font” property)

类似Font属性

- paReadOnly
value cannot be changed in the editor; some properties, of “Class” or “Set” types, have this attribute

只读的属性

- paOwnerDraw
property value is drawn by the “OnDrawItem” method; if the “paValueList” attribute is present then a drop-down list is drawn by the OnDrawLBItem method

自绘的属性,重写OnDrawItem方法.

The Edit method is called in two ways: either by selecting a property and double-clicking its value or (if property has paDialog attribute) by clicking the '...' button. This method should return “True” if property value was modified.

The “GetValue” method should return the property value as a string (it will be displayed in the object inspector). If you inherit from the TfrxPropertyEditor base class this method must be overridden.

The “SetValue” method is to set the property value, transferred as a string. If you inherit from the TfrxPropertyEditor base class this method must be overridden.

The “GetValues” method should be overridden if the “paValueList” attribute is set. This method should fill the “Values” property with values.

 

The following three methods allow manual drawing of the property value (the Color property editor works in the same way). These methods are called if the “paOwnerDraw” attribute is set.

以下3个方法手动绘制属性值。如果attribute 设置为paOwnerDraw.

The “OnDrawItem” method is called when the property value is drawn in the object inspector (when the property is not selected; otherwise its value is simply displayed in the editing line). For example, the Color property editor draws a rectangle to the left of property value, filled with the corresponding color.

The “GetExtraLBSize” method is called if the “paValueList” attribute is set. This method returns the number of pixels by which to adjust the “Drop-Down List” width to display the list. By default this method returns the value corresponding to the cell height. If you need to draw picture, with width larger than its height, the given method should be overridden.

The “OnDrawLBItem” method is called when drawing a string in a drop-down list if the paValueList attribute is set. This method is actually the TListBox.OnDrawItem event handler and has the same set of parameters.

 

Property editor registration is performed by the procedure defined in the frxDsgnIntf file:

属性编辑器的注册调用以下过程,声明在frxDsgnIntf 文件:

procedure frxPropertyEditors.Register(PropertyType: PTypeInfo;ComponentClass: TClass;const PropertyName: String;

EditorClass: TfrxPropertyEditorClass);

- PropertyType
information about the property type, returned by the “TypeInfo” system function, for example TypeInfo(String)

- ComponentClass
component name, with property you want to edit (may be nil)

- PropertyName
name of property you want to edit (may be a blank string)

- EditorClass
property editor name

Only the “PropertyType” parameter needs to be specified. The “ComponentClass” and/or “PropertyName” parameters may be blank. This allows the editor to be registered either to any property of PropertyType type, to any property of concrete ComponentClass components and its descendants, or to a PropertyName specific property of a specific component (or to any component if the ComponentClass parameter is blank).

参数PropertyType是必须的,其他可以不输入。

 

Let's look at three property editor examples. FastReport requires the Editor code to be placed in a file having the same name as the file having the component code, with 'Editor' suffixed to it.

举例:属性编辑器的代码文件用跟组件同样的文件名,加Editor做后缀存放。

--------------------------------------------------

{ TFont property editor displays editor button('...') }  //字体属性编辑器

{ inherit from ClassProperty }

type

TfrxFontProperty = class(TfrxClassProperty)

public

//重写的方法

function Edit: Boolean; override;

function GetAttributes: TfrxPropertyAttributes; override;

end;

function TfrxFontProperty.GetAttributes: TfrxPropertyAttributes;

begin

{ property has nested properties and editor;it cannot be edited manually }

Result := [paMultiSelect, paDialog, paSubProperties, paReadOnly];

end;

function TfrxFontProperty.Edit: Boolean;

var

FontDialog: TFontDialog;

begin

{ create standard dialogue }

FontDialog := TFontDialog.Create(Application);

try

{ take property value }

FontDialog.Font := TFont(GetOrdValue);

FontDialog.Options := FontDialog.Options + [fdForceFontExist];

{ display dialogue }

Result := FontDialog.Execute;

{ bind new value }

if Result then

SetOrdValue(Integer(FontDialog.Font));

finally

FontDialog.Free;

end;

end;

{ registration }  //注册

frxPropertyEditors.Register(TypeInfo(TFont), nil, '', TfrxFontProperty);

--------------------------------------------------

{ TFont.Name property editor displays a drop-down list of available fonts; inherit from StringProperty, as property is of string type }

type

TfrxFontNameProperty = class(TfrxStringProperty)

public

function GetAttributes: TfrxPropertyAttributes; override;

procedure GetValues; override;

end;

function TfrxFontNameProperty.GetAttributes: TfrxPropertyAttributes;

begin

Result := [paMultiSelect, paValueList];

end;

procedure TfrxFontNameProperty.GetValues;

begin

Values.Assign(Screen.Fonts);

end;

{ registration }

frxPropertyEditors.Register(TypeInfo(String), TFont,'Name', TfrxFontNameProperty);

--------------------------------------------------

{ TPen.Style property editor displays a picture,which is an example of the selected style }

type

TfrxPenStyleProperty = class(TfrxEnumProperty)

public

function GetAttributes: TfrxPropertyAttributes; override;

function GetExtraLBSize: Integer; override;

procedure OnDrawLBItem(Control: TWinControl; Index: Integer;ARect: TRect; State: TOwnerDrawState); override;

procedure OnDrawItem(Canvas: TCanvas; ARect: TRect); override;

end;

function TfrxPenStyleProperty.GetAttributes: TfrxPropertyAttributes;

begin

Result := [paMultiSelect, paValueList, paOwnerDraw];

end;

{ method draws thick horizontal line with selected style }

procedure HLine(Canvas: TCanvas; X, Y, DX: Integer);

var

i: Integer;

begin

with Canvas do

begin

Pen.Color := clBlack;

for i := 0 to 1 do

begin

MoveTo(X, Y - 1 + i);

LineTo(X + DX, Y - 1 + i);

end;

end;

end;

{ drawing drop-down list }

procedure TfrxPenStyleProperty.OnDrawLBItem(Control: TWinControl; Index: Integer;ARect: TRect; State: TOwnerDrawState);

begin

with TListBox(Control), TListBox(Control).Canvas do

begin

FillRect(ARect);

TextOut(ARect.Left + 40, ARect.Top + 1, TListBox(Control).Items[Index]);

Pen.Color := clGray;

Brush.Color := clWhite;

Rectangle(ARect.Left + 2, ARect.Top + 2,

ARect.Left + 36, ARect.Bottom - 2);

Pen.Style := TPenStyle(Index);

HLine(TListBox(Control).Canvas, ARect.Left + 3,

ARect.Top + (ARect.Bottom - ARect.Top) div 2, 32);

Pen.Style := psSolid;

end;

end;

{ drawing property value }

procedure TfrxPenStyleProperty.OnDrawItem(Canvas: TCanvas; ARect: TRect);

begin

with Canvas do

begin

TextOut(ARect.Left + 38, ARect.Top, Value);

Pen.Color := clGray;

Brush.Color := clWhite;

Rectangle(ARect.Left, ARect.Top + 1,

ARect.Left + 34, ARect.Bottom - 4);

Pen.Color := clBlack;

Pen.Style := TPenStyle(GetOrdValue);

HLine(Canvas, ARect.Left + 1,

ARect.Top + (ARect.Bottom - ARect.Top) div 2 - 1, 32);

Pen.Style := psSolid;

end;

end;

{ return picture width }

function TfrxPenStyleProperty.GetExtraLBSize: Integer;

begin

Result := 36;

end;

{ registration }

frxPropertyEditors.Register(TypeInfo(TPenStyle), TPen,'Style', TfrxPenStyleProperty);

 

参考 frxADOEditor.pas 单元的使用。

[翻译] Writing Property Editors 编写属性编辑器的更多相关文章

  1. [翻译]Writing Component Editors 编写组件的编辑器

    Writing Component Editors  编写组件的编辑器   All common control editors (opened from a control's context me ...

  2. [翻译]Writing Custom Wizards 编写自定义的向导

    Writing Custom Wizards  编写自定义的向导   You can extend FastReport's functionality with the help of custom ...

  3. [翻译]Writing Custom DB Engines 编写定制的DB引擎

    Writing Custom DB Engines  编写定制的DB引擎   FastReport can build reports not only with data sourced from ...

  4. 用mel编写自定义节点的属性编辑器界面

    用mel编写自定义节点的属性编辑器界面比较麻烦,而且网上例子又少,下面给出一个范例,说明基本的格式 // 初始化节点时调用 global proc initControl(string $attrNa ...

  5. (spring-第13回【IoC基础篇】)PropertyEditor(属性编辑器)--实例化Bean的第五大利器

    上一篇讲到JavaBeans的属性编辑器,编写自己的属性编辑器,需要继承PropertyEditorSupport,编写自己的BeanInfo,需要继承SimpleBeanInfo,然后在BeanIn ...

  6. Spring 学习笔记 数据绑定,校验,BeanWrapper 与属性编辑器

    Spring 数据绑定,校验,BeanWrapper,与属性编辑器 Data Binding 数据绑定(Data binding)非常有用,它可以动态把用户输入与应用程序的域模型(或者你用于处理用户输 ...

  7. sprin源码解析之属性编辑器propertyEditor

    目录 异常信息 造成此异常的原因 bean 配置文件 调用代码 特别说明: 异常解决 注册springt自带的属性编辑器 CustomDateEditor 控制台输出 属性编辑器是何时并如何被注册到s ...

  8. 属性编辑器,即PropertyEditor-->Spring IoC

    在Spring配置文件里,我们往往通过字面值为Bean各种类型的属性提供设置值:不管是double类型还是int类型,在配置文件中都对应字符串类型的字面值.BeanWrapper填充Bean属性时如何 ...

  9. Spring经常使用属性的注入及属性编辑器

    对于对象的注入,我们使用ref方式,能够指定注入的对象.以下看下对于基本类型的注入.以及当spring无法转换基本类型进行注入时,怎样编写一个相似转换器的东西来完毕注入. 一.基本类型的注入 以下写一 ...

随机推荐

  1. 移动端开发之px,em和rem详解

    px:表示的是绝对的像素值,1px就是1像素大小 em:关于em,网上有资料说是关于父元素的,但是其实个人感觉这种说法是不对的,其实em的大小是根据自身的font-size确定的,而只是正常的情况下子 ...

  2. <meta name="viewport" content="width=device-width, initial-scale=1.0">的说明

    今天在做适配手机版时,chrome调到手机版,但是还是显示PC端的样式,无法展现出手机端的样式: 开始的时候还以为是chrome版本的问题,最新版本的chrome62.0是有很多变化的,而之前工作中使 ...

  3. native关键字(本地方法)、 java调用so动态链接库

    Java native关键字 一. 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个ja ...

  4. PHP分多步骤填写发布信息的简单方法实例代码

    1.php 复制代码 代码如下: <form name=form1 id=form1 method=post action=2.php> 基本信息1:<input type=text ...

  5. springboot获取项目跟目录

      springboot部署之后无法获取项目目录的问题: 之前看到网上有提问在开发一个springboot的项目时,在项目部署的时候遇到一个问题:就是我将项目导出为jar包,然后用java -jar ...

  6. 深入理解基于selenium的二次开发

    对于做web端自动化测试的人来说,可能接触selenium比QTP还要多,但是我们在做基于selenium的二次开发的时候,经常会说到二次开发是为了易于维护,很多人可能不懂得维护的价值是什么,和到底要 ...

  7. red ant

    Red Ant(红蚁)网络运维管理系统是IT运维管理系统,提供智能的B/S接口可视化人机界面,通过简单的操作实现全方位的网络专线.服务器.中间件.各种应 用程序.机房动力环境等监控管理,“化繁为简”, ...

  8. 【CentOS 6.5】安装gcc-4.8.2和Qt5.2

    因为CentOS6.5中gcc版本比较低.安装Qt5.2前先升级gcc. 首先下载gcc,附上百度盘地址:http://pan.baidu.com/s/1jGibvqY 解压安装包,并进入到解压文件夹 ...

  9. 如何用git命令行上传本地代码到github

    注意:安装的前提条件是配置好Git的相关环境或者安装好git.exe,此处不再重点提及 上传的步骤: 本文采用git 命令界面进行操作,先执行以下两个命令,配置用户名和email[设置用戶名和e-ma ...

  10. mysql 获取一段时间的数据

    用 sql 获取一段时间内的数据: SELECT * FROM EDI.edi_history WHERE timestampdiff(day, SYSDATE(), create_time_loc) ...