如何为某种类型的所有实例实现自己的自定义属性编辑器? [英] How can I implement my own custom property editor for all instances of a certain type?

查看:161
本文介绍了如何为某种类型的所有实例实现自己的自定义属性编辑器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经点了几个关于创建自定义属性编辑器对话框的教程,但是有很多事情涉及到我无法让它正常工作。我想要完成的是具有日期选择器(日历),时间选择器和确定和取消按钮的自定义表单。表单根本就没有问题,但是我将如何实现这一点,以便我可以通过按钮启动属性编辑器来发布某种类型的任何组件中的属性。

I have followed a few tutorials on creating a custom property editor dialog, but there are so many things involved that I could not get it to work right. What I am trying to accomplish is a custom form with a date picker (calendar), a time picker, and OK and Cancel buttons. The form is no problem at all, but how would I go about implementing this so that I can publish a property in any component of a certain type with a button to launch the property editor?

我想完全覆盖 TDateTime 类型,并将我的自定义编辑器放在其位置,所以无论哪里一个 TDateTime 在Object Inspector中发布并显示,我可以使用此编辑器在同一窗口中一起修改日期和时间。

I would like to completely override the TDateTime type and put my custom editor in its place, so wherever a TDateTime is published and visible in the Object Inspector, I can use this editor to modify both date and time together in the same window.

问题是文档创建一个自定义属性编辑器很差,虽然一些资源非常彻底,但是它们的功能太多细节,并且在最常见的情况下缺乏应用。

The problem is that the documentation on creating a custom property editor is poor and although some resources are very thorough, they go into too much detail of the capabilities and lack getting to the point on the most common scenarios.

推荐答案

我不想在这里提出这个问题,期望有人为我回答,所以我自己做了研究来解决我的问题,我想分享一下独特的经验这个迷你项目,像我一样肯定别人感到沮丧同样的事情。

I did not want to ask this question here and expect anyone to answer it for me, so I did the research myself to solve my issues and I would like to share the unique experience involved in this mini project, as I'm sure others are frustrated with the same thing.

有自定义属性编辑器,对话框和组件编辑器很多不同的可能性。这特别要求一个 TDateTimeProperty descendant。这将允许您在保持DateTime格式的同时,直接在对象检查器中编辑属性的值(以纯文本(String)形式)。

There are many different possibilities with custom property editors, dialogs, and component editors. This in particular would call for a TDateTimeProperty descendant. This would allow you to be able to edit the value of the property directly in the Object Inspector as plain text (String) while keeping the DateTime formatting.

我假设你已经有一个关于创建自定义组件的一般知识和一个包,您可以在其中发布此属性编辑器,因为这是一个我自己不会介绍的教训。这需要的代码只是一条线被放置在注册程序里面,但我们会在稍后谈到。

I am assuming that you already have a general knowledge of creating custom components and a package in which you can publish this property editor from, because that's a lesson in its own which I will not cover. This calls for just one line of code to be placed inside the Register procedure, but we'll get to that later.

首先,您需要在您的组件注册的 Design-Time 包中创建一个新表单。命名单位 DateTimeProperty.pas ,并命名表单 DateTimeDialog (从而使表单的类 TDateTimeDialog )。放置您需要的任何控件,在这种情况下, TMonthCalendar TDateTimePicker (含设置为 dtkTime )和2 TBitBtn 控件,一个标记为 OK ModalResult mrOK ,另一个标记为取消 ModalResult mrCancel

First, you need to create a new form in your Design-Time package, where your components are registered. Name the unit DateTimeProperty.pas, and name the form DateTimeDialog (thus making the form's class TDateTimeDialog). Place whatever controls you need, in this case a TMonthCalendar, TDateTimePicker (with Kind set to dtkTime), and 2 TBitBtn controls, one labeled OK with ModalResult of mrOK and the other labeled Cancel with ModalResult of mrCancel.

您的单位应该是这样的:

Your unit should look something like this:

unit DateTimeProperty;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.ComCtrls, Vcl.StdCtrls, Vcl.Buttons;

type
  TDateTimeDialog = class(TForm)
    dtDate: TMonthCalendar;
    dtTime: TDateTimePicker;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
  private

  public

  end;         

var
  DateTimeDialog: TDateTimeDialog;

implementation

{$R *.dfm}

end.

这里是这里的 DFM 代码形式:

And here is the DFM code behind this form:

object DateTimeDialog: TDateTimeDialog
  Left = 591
  Top = 158
  BorderIcons = [biSystemMenu]
  BorderStyle = bsToolWindow
  Caption = 'Pick Date/Time'
  ClientHeight = 231
  ClientWidth = 241
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  DesignSize = (
    241
    231)
  PixelsPerInch = 96
  TextHeight = 13
  object dtDate: TMonthCalendar
    Left = 8
    Top = 31
    Width = 225
    Height = 166
    Anchors = [akLeft, akRight, akBottom]
    Date = 41261.901190613430000000
    TabOrder = 1
  end
  object dtTime: TDateTimePicker
    Left = 8
    Top = 8
    Width = 113
    Height = 21
    Date = 41261.000000000000000000
    Time = 41261.000000000000000000
    Kind = dtkTime
    TabOrder = 2
  end
  object BitBtn1: TBitBtn
    Left = 158
    Top = 200
    Width = 75
    Height = 25
    Caption = 'OK'
    Default = True
    ModalResult = 1
    TabOrder = 0
  end
  object BitBtn2: TBitBtn
    Left = 77
    Top = 200
    Width = 75
    Height = 25
    Caption = 'Cancel'
    ModalResult = 2
    TabOrder = 3
  end
end

现在,将 DesignEditors DesignIntf​​ 添加到您的使用子句。确保在 Design-Time 要求中声明的 DesignIDE $ c>包。这是发布任何属性编辑器所必需的。

Now, add DesignEditors and DesignIntf to your uses clause. Make sure you have DesignIDE declared in the Requires of this Design-Time package. This is required for publishing any property editors.

在表单中,创建一个名为 DateTime 的新公共属性具有属性getter和setter的 TDateTime 该属性将允许您轻松地读取/写入选择实际表示的完整的 TDateTime 值。所以,你应该有这个在您的形式:

In the form, create a new public property called DateTime of type TDateTime with a property getter and setter. This property will allow you to easily read/write the full TDateTime value the selection actually represents. So you should have this in your form:

private
  function GetDateTime: TDateTime;
  procedure SetDateTime(const Value: TDateTime);
public
  property DateTime: TDateTime read GetDateTime write SetDateTime;

....

function TDateTimeDialog.GetDateTime: TDateTime;
begin
  Result:= Int(dtDate.Date) + Frac(dtTime.Time);
end;

procedure TDateTimeDialog.SetDateTime(const Value: TDateTime);
begin
  dtDate.Date:= Value;
  dtTime.DateTime:= Value;
end;



接下来,我们需要添加实际的属性编辑器类。在 {$ R * .dfm} 之下创建这个类,它刚刚在实现之下:

Next we need to add the actual property editor class. Create this class just beneath the {$R *.dfm} which is just under implementation:

type
  TDateTimeEditor = class(TDateTimeProperty)
  public
    procedure Edit; override;
    function GetAttributes: TPropertyAttributes; override;
    function GetValue: String; override;
    procedure SetValue(const Value: String); override;
  end;

procedure TDateTimeEditor.Edit;
var
  F: TDateTimeDialog;
begin
  //Initialize the property editor window
  F:= TDateTimeDialog.Create(Application);
  try
    F.DateTime:= GetFloatValue;
    if F.ShowModal = mrOK then begin
      SetFloatValue(F.DateTime);
    end;
  finally
    F.Free;
  end;
end;

function TDateTimeEditor.GetAttributes: TPropertyAttributes;
begin
  //Makes the small button show to the right of the property
  Result := inherited GetAttributes + [paDialog];
end;

function TDateTimeEditor.GetValue: String;
begin
  //Returns the string which should show in Object Inspector
  Result:= FormatDateTime('m/d/yy h:nn:ss ampm', GetFloatValue);
end;

procedure TDateTimeEditor.SetValue(const Value: String);
begin
  //Assigns the string typed in Object Inspector to the property
  inherited;
end;

最后,我们需要添加一个注册执行这个新的属性编辑器的实际注册的过程:

Finally, we need to add a Register procedure to perform the actual registration of this new property editor:

procedure Register;
begin
  RegisterPropertyEditor(TypeInfo(TDateTime), nil, '', TDateTimeEditor);
end;

现在,在调用 RegisterPropertyEditor 。由于第二和第三个参数是 nil 和一个空字符串,这意味着编辑器将适用于 TDateTime 的所有实例。查看此过程以获取有关使其具体到特定组件和属性实例的更多信息。

Now there's an important piece to understand in this call to RegisterPropertyEditor. Since the 2nd and 3rd parameters are nil and an empty string, this means the editor will apply to all instances of TDateTime. Look into this procedure for more information about making it specific to certain components and property instances.

这是安装后的最终结果...

And here's the final result after installing...

贡献的自定义属性编辑器的一些很好的资源如下所示:

Some good resources for custom property editors which contributed are as follows:


  1. 如何使自定义组件属性

  2. http://delphi.about.com/library/bluc/text/uc092501d.htm

  3. http://www.sandownet.com/propedit.html

  1. how to make custom component property?
  2. http://delphi.about.com/library/bluc/text/uc092501d.htm
  3. http://www.sandownet.com/propedit.html

这篇关于如何为某种类型的所有实例实现自己的自定义属性编辑器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆