Delphi 编写属性编辑器-我需要一些指导
概述 我正在创建一个从TCustomTreeView派生的组件,我想添加一个属性,该属性在对象检查器中显示一个下拉列表(paValueList?)。此列表必须基于附加到我的控件的另一个列表(TStrings)动态填充,例如,它可以是TComboBox、TListBox中的项目或TStringList中的字符串等 我有一些问题,但我真的可以做一些指导和建议Delphi 编写属性编辑器-我需要一些指导,delphi,custom-controls,delphi-xe,Delphi,Custom Controls,Delphi Xe,概述 我正在创建一个从TCustomTreeView派生的组件,我想添加一个属性,该属性在对象检查器中显示一个下拉列表(paValueList?)。此列表必须基于附加到我的控件的另一个列表(TStrings)动态填充,例如,它可以是TComboBox、TListBox中的项目或TStringList中的字符串等 我有一些问题,但我真的可以做一些指导和建议 代码布局 我缩短了代码以使其更易于阅读,但布局基本上与我的相同 我已将我的组件包分为两个(相同的项目组),Package1包含组件代码(例如
代码布局 我缩短了代码以使其更易于阅读,但布局基本上与我的相同 我已将我的组件包分为两个(相同的项目组),
Package1
包含组件代码(例如我的组件源自TCustomTreeView),而Package2
包含注册过程和设计器单元(designide.dcp、DesignIntf、DesignEditors等)
Package2
是我认为需要添加属性编辑器的地方,该编辑器将用于从Package1
中的TCustomTreeView派生的组件
包装1
unit MyTreeViewUnit;
implementation
uses
...
Classes,
SysUtils;
type
TMyTreeView = class(TCustomTreeView)
private
FSomeList: TStringList; // property editor should be filled using this list
procedure SetSomeList(const Value: TStringList);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property SomeList: TStringList read FSomeList write SetSomeList;
end;
....
包装2
unit MyTreeViewPropUnit;
implementation
uses
DesignIntf,
DesignEditors,
Classes;
type
TMyTreeViewProperty = class(TStringProperty)
public
function GetAttributes: TPropertyAttributes; override;
procedure GetValues(Proc: TGetStrProc); override;
procedure Edit; override;
end;
implementation
uses
MyTreeViewUnit;
function TMyTreeViewProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paValueList]; ?
end;
procedure TMyTreeViewProperty.GetValues(Proc: TGetStrProc);
begin
inherited;
// These cannot be added here!!
// This list should be populated based on SomeList found in Package1 - MyTreeViewUnit.pas
Proc('Item1');
Proc('Item2');
end;
procedure TMyTreeViewProperty.Edit;
begin
inherited;
// ?
end;
问题
非常感谢 这对于注释来说太长了,我想包含一些代码,所以这里有一个答案。首先,你的问题很广泛。你需要把事情搞清楚,这样你才能问到重点问题。事实上,我开始回答你的第二个问题,在我放弃之前很久,我写了一些不可读的东西 您应该从不需要属性编辑器的代码开始,即正常的运行时代码。属性编辑器不能成为自定义控件开发的中心,因为属性编辑器仅在设计时用于加快速度。如果要持久化特性编辑器所做的更改,则这些更改将保存到“对象检查器”(Object Inspector)中以任何方式可见的已发布特性(*1),这些特性将依次保存到DFM文件中。在创建表单的运行时和重新打开表单的设计时(例如:如果关闭IDE并重新打开它),会还原相同的过程。由于所有内容都需要进入对象检查器,因此您可以跳过花哨的属性编辑器,使控件正常工作 是什么促使我这么说的:
procedure TMyTreeViewProperty.GetValues(Proc: TGetStrProc);
begin
inherited;
// These cannot be added here!!
// This list should be populated based on SomeList found in Package1 - MyTreeViewUnit.pas
Proc('Item1');
Proc('Item2');
end;
该评论告诉我,您还没有弄清楚如何将组件链接到其他组件!这实际上是一个微不足道的步骤,一旦你完成了这项工作,你就可以这样做:
procedure TMyTreeViewProperty.GetValues(Proc: TGetStrProc);
var s: string;
begin
if Assigned(FLinkedCombo) then
for s in FLinkedCombo.Items do
Proc(s); // Beware, written in Browser!
end;
即使是那些无关紧要的问题,如果没有这一部分,上述问题的答案也是不完整的,而这一部分包括关于TComponent.FreeNotification
、TComponent.RemoveFreeNotification
和TComponent.Notification
的长谈
一旦您的大部分工作正常,就可以开始使用您可能想要创建的任何属性编辑器。这项工作也将作为一个普通项目来完成:您的目标是创建一个简单的表单(例如tmycomponentseteditor
),可以编辑您的属性或组件。完成该工作后,您可以问:如何使此工作编辑器在设计时作为属性或组件编辑器可用
*1) 当然,组件编辑器可以做涉及多个组件的奇特工作;它还可以使用其他方法保存内容(即:不依赖简单的已发布属性)。如果您有DevExpress垂直网格控件,您会发现它包含一个非常好的属性编辑器组件。我开始写我自己的一本,然后我发现我已经有了一个非常好的版本。您可以在此处找到更多信息:您已经为名为
Test
的TMyTreeView
字符串属性注册了属性编辑器,但是TMyTreeView
在您发布的代码中没有属性Test
。你希望属性编辑器准确地编辑什么?我注意到,也应该是'SomeList'
而不是'Test'
@KenWhite阅读我对Cosmin Prund的回答的评论,你会再次发现,像往常一样,我在一个问题上停留的时间太长,对我手头的任务更加困惑。我真的需要学会停止跳槽,而是坐下来,花时间了解信息和文档指南等。我似乎在说服自己,一切都会很容易做到,到那时,我已经太晚了,感到困惑和沮丧。我似乎不能保持清醒的头脑,看到并理解我一直在做的每件事,但我会继续努力!嗨,很抱歉回复晚了。我想在写这个问题的时候,我处于一种困惑的状态,所以我写的问题并不像我希望的那么清楚。在t之前,我需要花一些时间阅读更多关于属性编辑器的内容
procedure TMyTreeViewProperty.GetValues(Proc: TGetStrProc);
var s: string;
begin
if Assigned(FLinkedCombo) then
for s in FLinkedCombo.Items do
Proc(s); // Beware, written in Browser!
end;