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

发布于 2024-10-03 20:19:26 字数 750 浏览 0 评论 0原文

我有一个源自 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 过程设置一个标志,以了解它何时必须执行其他操作(除了重新绘制组件之外)。有办法实现这一点吗?

I have a custom Delphi component descending from TGraphicControl. Its class is declared as follows :

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

The implementation of SetWidth lies further :

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;

I currently get SetWidth called when the width of the component is changed programmatically at runtime or at design time by entering a value in the corresponding field of the object inspector. However, when I resize the component at design time using the mouse, the object inspector 'Width' field is updated but no message box shows up, so my SetWidth procedure is not called.

I need SetWidth to be called while mouse-resizing the component, so that I can set a flag for the Paint procedure to know when it must do some other stuff (besides just redrawing the component). Is there a way to achieve this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你げ笑在眉眼 2024-10-10 20:19:26

虽然梅森惠勒的答案是你的问题,我想警告你。

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

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

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

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

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

While Mason Wheeler's answer is the answer to your question, I would like to warn you.

Overriding properties can give strange results since you can't have 'virtual' properties and SetWidth is also not virtual. If someone is using a descendant of your class to set the Width property, your code would not be called. Therefore I advice against overriding properties in this way.

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

Furthermore: setting the Width property is not the only way to change the width of a control as Deltics explains. You should override TControl.SetBounds.

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

But it seems like you want to limit the width of your control. Then you better override TControl.CanResize which is made for that purpose. Or if you just want to react to a resize of any kind you better override TControl.Resize.

回忆躺在深渊里 2024-10-10 20:19:26

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

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

I can't check right now, but iirc I suspect that the designer resizes your control using SetBounds() rather than setting individual left, top, width and height properties.

Fortunately, SetBounds() is virtual so you can simply override this in your custom control class.

银河中√捞星星 2024-10-10 20:19:26

当您重新声明宽度时,您需要为其指定读取写入,否则您将无法在对象检查器中修改它。如果您不打算改变阅读的方式,那么只需给它一个虚拟函数:

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

When you redeclare Width, you need to specify both the read and the write for it or you won't be able to modify it in the Object Inspector. If you're not going to change the way reading works, then just give it a dummy function:

procedure TMyLabel.GetWidth: Integer;
begin
  result := inherited Width;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文