在 Delphi VCL 中通过组合两个控件(TEdit 和 TTrackBar)创建一个新组件

Posted

技术标签:

【中文标题】在 Delphi VCL 中通过组合两个控件(TEdit 和 TTrackBar)创建一个新组件【英文标题】:Creating a new component by combining two controls (TEdit and TTrackBar) in Delphi VCL 【发布时间】:2018-01-25 02:57:15 【问题描述】:

我正在为 Windows 开发一个 Delphi 10.1 VCL 应用程序。

对于整数或浮点输入,我需要一个与滑块连接的数字输入字段。当用户更改输入字段中的数字时,滑块位置会相应更改。当用户更改滑块位置时,数字字段中的数字会更新。

我可以通过使用TEditTTrackBar 来解决这个问题,并在它们的OnChange 事件处理程序中添加必要的更新功能。

问题是我需要许多不同形式的此类输入。因此,我想创建一个新组件,将TEditTTrackBar 这两个控件组合在一个组件中。

    创建新组件是多次使用此类滑块输入的最佳策略吗?

    创建这样一个新组件的最佳方法是什么?

【问题讨论】:

我会从 TCustomControlSetSubComponent 派生这些子控件。剩下的就是将这些子控件发布为属性,或者发布一些基本的属性集(例如,这些子控件的值和位置)。另一种方法是使用框架,但存在有人将控件移动到内部的风险。 当然 :) 如果您将使用框架 (TFrame),您或其他人将能够分别在每个框架上移动容器内的控件(据我所知)。所以他们可以打破原来的控制布局(最终可能需要 - 取决于您的需要)。如果您创建复合控件,则不会发生这种情况。 我会为此使用TFrame。使用标准的TEditTTrackBar 以及相关的事件处理程序设计TFrame,然后只需将TFrame 的实例放在需要的地方。这一切都可以直观地完成,无需为其编写自定义组件。 问题问的是最好的方式,不是我会做或他/她会做。 @kobik - 不。因此我认为应该结束这个问题。 【参考方案1】:

创建一个新的组件是多方面的最佳策略吗? 使用这样的滑块输入?

不一定总是如此。 (至少按照我的标准)。

创建这样一个新组件的最佳方法是什么?

我知道解决您问题的三种方法。

方式一:

使用新组件向导创建组件,您可以在其中动态地创建 TEditTGroupBox 后代中的 TTrackBar 子组件。

以下是我的做法。

unit Combindedittrack;

interface

uses
  System.SysUtils,
  System.Classes,
  Vcl.Controls,
  Vcl.comctrls,
  Vcl.StdCtrls;

type
  TCombindEditTrack = class(TGroupBox)
  private
     Private declarations 
    FEdit: TEdit;
    FTrackBar: TTrackBar;
    procedure EditOnChangeProc(Sender: TObject);
    procedure TrackBaroOnChangeProc(Sender: TObject);
  protected
     Protected declarations 

  public
     Public declarations 
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
     Published declarations 
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TCombindEditTrack]);
end;

constructor TCombindEditTrack.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SetBounds(0, 0, 250, 50);
  FEdit := TEdit.Create(Self);
  with FEdit do
  begin
    Text := ''; //<-- you control the appearence here
    Top := 10;
    Left := 10;
    Height := 27;
    Width := 50;
    Parent := Self;
    OnChange := EditOnChangeProc; // your Onchange event handler for the Tedit
  end;

  FTrackBar := TTrackBar.Create(self);
  with FTrackBar do
  begin
    Top := 10; //<-- you control the appearence here
    Left := 60;
    Height := 30;
    Width := 50;
    Parent := self;
    Onchange := TrackBaroOnChangeProc; // your Onchange event handler for the Ttrackbar
  end;
end;

destructor TCombindEditTrack.Destroy;
begin
  FTrackBar.Free;
  FEdit.Free;
  inherited;
end;

procedure TCombindEditTrack.TrackBaroOnChangeProc(Sender: TObject);
begin
  // <-- track bar onchange handling here.
end;

procedure TCombindEditTrack.EditOnChangeProc(Sender: TObject);
begin
  // <-- edit onchange handling here.
end;

end.

方法二:

使用这样的框架(我在 delphi 10 西雅图)。

    文件-->新建-->其他-->(在delphi文件上搜索框架)。

    现在添加编辑和轨迹栏并设置它们的 Onchange 事件。

    保存单位。

    在工具面板(标准组件部分)上单击框架组件。

    选择您刚刚创建的框架。

每次使用时,您都会得到一个框架的副本。

方式3:

像这样使用组件模板(我又在 delphi 10 西雅图)

    选择您已经创建和修改的teditttrackbar

    在工具栏的“组件”上点击“创建组件模板”。

    为您的模板命名并按 OK。

    选择模板调色板,然后选择您的模板。

现在请注意,甚至您的代码(事件)也已添加到您的项目中。

终于

以我在 delphi 和 IDE 上的水平,我真的无法明确回答哪种方法是最好的,但我还是分享了我所知道的所有可以帮助你的东西。


编辑:因为很多 cmets 坚持回答应该说明哪种方法是最好的方法。这是基于以下的最佳方式。

让我们把选择时应该考虑的一些关键点放在一边

1.如果您愿意,可以轻松修改组合控件(根据我的经验,您会这样做)。

2. 完成此任务所需的时间(表示将花费的时间 以最少的调试和编码完成任务)。

3.一般源代码可读性。

4.对您项目的未来有用。

现在让我们根据这些标准开始批评这三种方法。

方式一:

C1(标准号 1):只需修改组件的源实现,每个副本/使用将具有相同的效果和属性。但是,第 3 路的情况并非如此。

C2:这取决于您对组件编写的了解,但是对于这个组件,我花了 5 分钟来创建它,而且我只是 delphi 的初学者。如果出现问题并且问题出在组件实现中,则调试时只需修复一次(参见 C1)

C3:它们在您的组件的表单源代码中没有实现,只需将其添加到您的表单中,所有内容都会被隐藏(例如添加 tedit 并查看表单源中的实现)。

C4:您正在创建一个组件,这将为您创建自己的组件集打开大门,例如 Flatstyle 或 Indy 开源组件。所以下次你需要这样的东西时,只需将其放入表单设计器中即可完成。

方式 2:

C1: 就像第 1 种方式一样,因为您正在创建一个组件,但这次是视觉上的。修改源框架会改变副本的效果和属性,您也可以为副本添加额外的处理。

replica的Onchange事件的事件处理器是这​​样的

procedure TForm1.Frame2Edit1Change(Sender: TObject);
begin
  Frame2.Edit1Change(Sender); //<-- this is the original onchange event you setup at the beginning 
  //<-- you can extra handling here if you want one of the replicas to behave differently than the original  
end;

C2:同一时间,可能比第 1 路更快。

C3:总的来说,它的结果与第 1 路相同。

C4:与第 1 种方式不同,您不能在项目 B 中使用在项目 A 中创建的框架。因此您的编码和调试将保留在项目 A 中。

方式3:组件模板。

C1:您不是在创建组件,而是在创建您在上一个项目中执行的确切步骤的复制/宏。改变一个不会改变他们分开的其他人。

C2:同一时间,可能比第 1 路更快。

C3:每次向表单添加模板时,都会添加事件代码(如果是长 Onchange 代码,则视图不好)。

C4:您可以在项目B中使用在项目A中创建的模板。但是您在项目A中编写的内容将在项目B中(参见c1),即使是不存在的变量的引用在项目 B 中(考虑到每次使用模板之间的时间段,这可能很难调试和误导)。

结论: 提出的每一种方式都将花费时间进行编码和调试,并且它们都将完成任务,但是为了简单起见和以最小风险重用,方式 1 是这里是安全的选择,因为它会让您有机会安全地更新和升级。调试也更快。

方法 1 的好处是,一段时间后您会忘记实现以及内部工作的方式。唯一应该记住的是组件的用途,因为它将成为您使用的各种组件之一(您不知道Tedit 是如何实现的,您不需要但您使用它您创建的每个项目)。

根据给定的标准,1 号方式是最好的

【讨论】:

问题问哪个最好。如果您必须回答,您当然需要说明并证明哪个是最好的。 如果问题是“哪个最好”,这是否意味着它“主要基于意见”,因此不允许这样做? @NasreddineAbdelillahGalfout 读一读:***.com/help/closed-questions这当然意味着这个问题是基于意见的,应该这样结束吗? @DavidHeffernan 我读了它,你是对的,它是基于意见的,因此应该关闭。【参考方案2】:

您可以创建一个框架,然后将该框架注册为一个组件。最终结果与创建仅代码组件非常相似,其中子组件在构造函数中创建(Nasreddine 的第 1 个选项)。但是,此方法允许您直观地设计组件并使用对象检查器来创建事件处理程序。

这是一个 Stack Overflow 问题,展示了如何注册框架: How to Improve the Use of Delphi Frames

【讨论】:

【参考方案3】:

也许使用包含这两个控件的容器控件是一种更简单的选择。我正在为此使用 ccpack。

https://sourceforge.net/projects/ccpack/

自定义容器包 (CCPack) 是一个集成的工具和组件迷你 用于生成和维护复合控件(或简称为“复合”)的库 和其他容器(表单、数据模块和框架)。的过程 构建复合组件看起来像 ActiveForm 和 Frame 创建,但是 结果是本机 VCL 组件。您可以创建新的复合材料 像往常一样。

【讨论】:

CCPack 是一个伟大的 Delphi 工具,但被大大低估了!

以上是关于在 Delphi VCL 中通过组合两个控件(TEdit 和 TTrackBar)创建一个新组件的主要内容,如果未能解决你的问题,请参考以下文章

delphi 如何通过单击一个窗体的按钮给一个frame的控件赋值

delphi xe8 可以安装devexpress vcl14.2.2吗

用于Delphi的DevExpress VCL组件——富文本编辑功能升级

研究VCL源码的原因和起点

看看 Delphi XE2 为 VCL 提供的 14 种样式

转:看看 Delphi XE2 为 VCL 提供的 14 种样式