You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调整自定义Delphi组件TBtnsHints类的属性显示顺序

Delphi自定义组件:TBtnsHints属性排序的优雅解决方案

我在开发带颜色的自定义BindNavigator组件时,遇到TBtnsHints子属性排序的问题。目前通过给published属性加_n前缀来控制显示顺序(First、Prior……CancelUpdate),但这种方式不够优雅,有没有更好的实现方法?当前代码如下:

TBtnsHints = class (TPersistent)
private
  FOwner : TColoredBindNavigator;
  FButtonHints : TButtonHints;
  function GetHint(const index : Integer) : String;
  function HintisStored(const index: Integer) : Boolean;
  procedure SetHint(const index : Integer; const Value : String) ;
public
  constructor Create(aOwner : TColoredBindNavigator);
  destructor Destroy; override;
published
  property _1First : String index 0 read GetHint write SetHint stored HintisStored;
  property _2Prior : String index 1 read GetHint write SetHint stored HintisStored;
  property _3Next : String index 2 read GetHint write SetHint stored HintisStored;
  property _4Last : String index 3 read GetHint write SetHint stored HintisStored;
  property _5Insert : String index 4 read GetHint write SetHint stored HintisStored;
  property _6Delete : String index 5 read GetHint write SetHint stored HintisStored;
  property _7Edit : String index 6 read GetHint write SetHint stored HintisStored;
  property _8Post : String index 7 read GetHint write SetHint stored HintisStored;
  property _9Cancel : String index 8 read GetHint write SetHint stored HintisStored;
  property __0Refresh : String index 9 read GetHint write SetHint stored HintisStored;
  property __1ApplyUpdate : String index 10 read GetHint write SetHint stored HintisStored;
  property __2CancelUpdate : String index 11 read GetHint write SetHint stored HintisStored;
end;

方案1:使用[Order]属性修饰符(Delphi XE及以上版本)

从Delphi XE开始,官方提供了[Order(N)]元数据标签,可以直接指定设计器中属性的显示顺序,N值越小,属性越靠前。这种方法无需额外代码,是最简洁的解决方案:

TBtnsHints = class (TPersistent)
private
  FOwner : TColoredBindNavigator;
  FButtonHints : TButtonHints;
  function GetHint(const index : Integer) : String;
  function HintisStored(const index: Integer) : Boolean;
  procedure SetHint(const index : Integer; const Value : String) ;
public
  constructor Create(aOwner : TColoredBindNavigator);
  destructor Destroy; override;
published
  [Order(0)]
  property First : String index 0 read GetHint write SetHint stored HintisStored;
  [Order(1)]
  property Prior : String index 1 read GetHint write SetHint stored HintisStored;
  [Order(2)]
  property Next : String index 2 read GetHint write SetHint stored HintisStored;
  [Order(3)]
  property Last : String index 3 read GetHint write SetHint stored HintisStored;
  [Order(4)]
  property Insert : String index 4 read GetHint write SetHint stored HintisStored;
  [Order(5)]
  property Delete : String index 5 read GetHint write SetHint stored HintisStored;
  [Order(6)]
  property Edit : String index 6 read GetHint write SetHint stored HintisStored;
  [Order(7)]
  property Post : String index 7 read GetHint write SetHint stored HintisStored;
  [Order(8)]
  property Cancel : String index 8 read GetHint write SetHint stored HintisStored;
  [Order(9)]
  property Refresh : String index 9 read GetHint write SetHint stored HintisStored;
  [Order(10)]
  property ApplyUpdate : String index 10 read GetHint write SetHint stored HintisStored;
  [Order(11)]
  property CancelUpdate : String index 11 read GetHint write SetHint stored HintisStored;
end;

方案2:自定义属性编辑器(兼容旧版Delphi)

如果需要支持Delphi XE之前的版本,可通过编写自定义属性编辑器来强制控制属性显示顺序:

第一步:注册自定义属性编辑器

在组件的注册单元中添加以下代码:

uses
  DesignEditors, DesignIntf;

type
  TBtnsHintsEditor = class(TPropertyEditor)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure GetProperties(Proc: TGetPropProc); override;
  end;

procedure Register;
begin
  RegisterPropertyEditor(TypeInfo(TBtnsHints), nil, '', TBtnsHintsEditor);
end;

{ TBtnsHintsEditor }
function TBtnsHintsEditor.GetAttributes: TPropertyAttributes;
begin
  Result := [paSubProperties];
end;

procedure TBtnsHintsEditor.GetProperties(Proc: TGetPropProc);
const
  PropOrder: array[0..11] of string = (
    'First', 'Prior', 'Next', 'Last', 'Insert', 'Delete',
    'Edit', 'Post', 'Cancel', 'Refresh', 'ApplyUpdate', 'CancelUpdate'
  );
var
  I: Integer;
  PropInfo: PPropInfo;
begin
  // 按自定义顺序遍历属性,传递给设计器显示
  for I := Low(PropOrder) to High(PropOrder) do
  begin
    PropInfo := GetPropInfo(GetComponent(0), PropOrder[I]);
    if Assigned(PropInfo) then
      Proc(PropInfo);
  end;
end;

第二步:清理TBtnsHints的属性名

去掉属性名前缀,恢复正常命名:

TBtnsHints = class (TPersistent)
private
  FOwner : TColoredBindNavigator;
  FButtonHints : TButtonHints;
  function GetHint(const index : Integer) : String;
  function HintisStored(const index: Integer) : Boolean;
  procedure SetHint(const index : Integer; const Value : String) ;
public
  constructor Create(aOwner : TColoredBindNavigator);
  destructor Destroy; override;
published
  property First : String index 0 read GetHint write SetHint stored HintisStored;
  property Prior : String index 1 read GetHint write SetHint stored HintisStored;
  property Next : String index 2 read GetHint write SetHint stored HintisStored;
  property Last : String index 3 read GetHint write SetHint stored HintisStored;
  property Insert : String index 4 read GetHint write SetHint stored HintisStored;
  property Delete : String index 5 read GetHint write SetHint stored HintisStored;
  property Edit : String index 6 read GetHint write SetHint stored HintisStored;
  property Post : String index 7 read GetHint write SetHint stored HintisStored;
  property Cancel : String index 8 read GetHint write SetHint stored HintisStored;
  property Refresh : String index 9 read GetHint write SetHint stored HintisStored;
  property ApplyUpdate : String index 10 read GetHint write SetHint stored HintisStored;
  property CancelUpdate : String index 11 read GetHint write SetHint stored HintisStored;
end;

方案3:数组属性替代独立属性(可选)

如果允许调整属性访问方式,可将所有提示封装为数组属性,设计器会按索引顺序显示,同时可保留命名属性作为快捷访问:

TBtnsHints = class (TPersistent)
private
  FOwner : TColoredBindNavigator;
  FButtonHints : TButtonHints;
  function GetHint(const index : Integer) : String;
  function HintisStored(const index: Integer) : Boolean;
  procedure SetHint(const index : Integer; const Value : String) ;
public
  constructor Create(aOwner : TColoredBindNavigator);
  destructor Destroy; override;
published
  property Hints[Index: Integer]: String read GetHint write SetHint stored HintisStored; default;
  // 保留命名属性方便直接访问
  property First : String index 0 read GetHint write SetHint stored HintisStored;
  property Prior : String index 1 read GetHint write SetHint stored HintisStored;
  // ... 其余属性同上
end;

内容的提问来源于stack exchange,提问作者SergeGirard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:16:00