delphi - Delphi 自定义组件,拖动时无法在设计器中定位(顶部/左侧属性的自定义设置器)
问题描述
我写了一个组件,它绘制以 X,Y 为中心的图片。在运行时,组件随SetXY(X,Y: integer)
过程移动。
为了实现这一点,我计算了绘制程序中的Left
和值并相应地设置它们。Top
所有这些都很好。
但是当我尝试在设计时进行初始定位时,我无法通过将组件拖动到所需位置来定位组件。
当我通过对象检查器设置Left
orTop
属性时,它可以工作。
procedure MyCustomComponent.SetTop(const Value: integer);
begin
if Top = (Value) then
exit;
inherited Top := Value;
if csDesigning in ComponentState then
FY := Value + FBmp.Width div 2;
Invalidate;
end;
procedure MyCustomComponent.SetLeft(const Value: integer);
begin
if Left = (Value) then
exit;
inherited Left := Value;
if csDesigning in ComponentState then
FX := Value + FBmp.Width div 2;
Invalidate;
end;
我怀疑当组件在窗体上的设计时拖放时,它实际上并没有设置Left
和Top
公共属性,而是调用一些其他函数来设置我继承组件的基础控件的私有字段成员( TGraphicControl
)。
解决方案
正如 fpiette 和 Remy 都指出的那样,覆盖SetBounds
就可以了。在设计时通过拖放组件定位组件时,它不会单独设置公共Left
和Top
属性。而是调用该SetBounds
过程。
procedure MyComponent.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited;
if csDesigning in ComponentState then begin
FX := ALeft + FBmp.Width div 2;
FY := ATop + FBmp.Height div 2;
end;
end;
编辑:
经过测试,我发现要在运行时将组件正确放置在表单上,您还必须检查csLoading
组件状态。
所以一个更完整的解决方案是这样的:
procedure MyComponent.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited;
if (csDesigning in ComponentState) or (csLoading in ComponentState ) then begin
FX := ALeft + FBmp.Width div 2;
FY := ATop + FBmp.Height div 2;
end;
end;
推荐阅读
- ios - 推送通知点击获取 url 并在 View Controller , iOS , Swift4.2 中显示
- javascript - 如何阻止 css translate 将元素带到前面?
- mysql - MySQL 多个唯一列
- jquery - Wordpress AJAX 调用返回未定义
- python - 递归上传目录(其中包含目录)到 FTP
- ionic-framework - 在生产构建离子3中没有获得本地通知声音
- javascript - 修复javascript中的变量增量
- redux - 使用 react-redux 如何在异步更新调用后端之前实现即时 UI,如果更新不成功则回滚?
- c# - 如何在 C# 中访问 JSON 对象的结果
- node.js - 带有node.js的对话流你如何切换意图