重新声明自定义 Delphi 组件的 Width 属性

Posted

技术标签:

【中文标题】重新声明自定义 Delphi 组件的 Width 属性【英文标题】:Redeclare Width property for a custom Delphi component 【发布时间】:2011-05-14 04:09:20 【问题描述】:

我有一个来自 TGraphicControl 的自定义 Delphi 组件。它的类声明如下:

TMyLabel = class(TGraphicControl)
private
  ...
protected
  ...
public
  ...
published
  property Height;
  property Width write SetWidth;
  ...
end;

SetWidth 的实现更进一步:

procedure TMyLabel.SetWidth(const Value: Integer);
begin
  if (Value >= 0) and (Value <> Width)
  then begin
    inherited Width := Value;
    // Do some other stuff
    ...
  end;
  MessageDlg('Test', mtInformation, [mbOK], 0);
end;

当前,当组件的宽度在运行时或设计时通过在对象检查器的相应字段中输入值以编程方式更改时,我会调用 SetWidth。但是,当我在设计时使用鼠标调整组件大小时,对象检查器的“宽度”字段会更新,但没有显示消息框,因此不会调用我的 SetWidth 过程。

我需要在鼠标调整组件大小时调用 SetWidth,以便我可以为 Paint 过程设置一个标志,以了解它何时必须执行其他操作(除了重绘组件之外)。有没有办法做到这一点?

【问题讨论】:

+1,因为它带来了 3 个很好且互补的答案。当然,它本身也有优点,如果只是为了避免错误;-) 【参考方案1】:

虽然Mason Wheeler's answer 是您问题的答案,但我想警告您。

覆盖属性可能会产生奇怪的结果,因为您不能拥有“虚拟”属性并且 SetWidth 也不是虚拟的。如果有人使用您的类的后代来设置 Width 属性,则不会调用您的代码。因此,我建议不要以这种方式覆盖属性。

var Control: TControl;
begin
 Control := MyLabel;
 Control.Width := 5000; // TMyLabel.SetWidth is not called!!

此外:设置 Width 属性并不是将控件宽度更改为Deltics explains 的唯一方法。你应该重写 TControl.SetBounds。

var MyLabel: TMyLabel;
begin
 MyLabel.SetBounds(0, 0, 100, 100); // TMyLabel.SetWidth nor TControl.SetWidth is called!!

但您似乎想限制控件的宽度。那么你最好覆盖为该目的而制作的 TControl.CanResize 。或者,如果您只想对任何类型的调整大小做出反应,最好覆盖 TControl.Resize

【讨论】:

感谢您的建议,我应该能够使用 TControl.Resize 解决我的问题。 嗨 Lars,我们这些普通人在这个网站上发帖的唯一也是非常原因,正是因为我们没有时间也没有技能去挖掘 vcl 源来查找任何能回答我们问题的东西。为此,我们依靠聪明人的专业知识,否则,该站点将毫无用处。这么说,恕我直言,我发现你答案的最后一句话,比方说,有点傲慢,绝对没有必要。最好的问候。 @user2383818,你是对的。我已经删除了这句话【参考方案2】:

我现在无法检查,但 iirc 我怀疑设计器使用 SetBounds() 调整控件的大小,而不是设置单独的左侧、顶部、宽度和高度属性。

幸运的是,SetBounds() 是虚拟的,因此您可以在自定义控件类中简单地覆盖它。

【讨论】:

【参考方案3】:

当您重新声明 Width 时,您需要为其指定 readwrite,否则您将无法在 Object Inspector 中对其进行修改。如果你不打算改变阅读的方式,那就给它一个虚拟函数:

procedure TMyLabel.GetWidth: Integer;
begin
  result := inherited Width;
end;

【讨论】:

谢谢,但我可以在对象检查器中更改组件的宽度而无需在属性声明中的写入访问器旁边指定读取访问器,这似乎很奇怪。

以上是关于重新声明自定义 Delphi 组件的 Width 属性的主要内容,如果未能解决你的问题,请参考以下文章

Delphi自定义函数声明及调用问题!

Delphi - 如何自定义 IDE 布局

Delphi 2009 - 在自定义 Delphi 组件中设置默认属性值

Delphi自定义组件如何在属性面板中实现打开文件的对话框?

如何在自定义 delphi 组件中实现 stringlist 属性?

在自定义 Delphi 组件中实现 Columns.Columns 属性