【问题标题】:When create subcomponents on a TDBGrid descendant?何时在 TDBGrid 后代上创建子组件?
【发布时间】:2021-10-05 16:20:02
【问题描述】:

我在 TDBGrid 后代上添加一个 ControlButton。

type TAEDBGrid = class(TDBGrid)
  private
    ControlButton: TButton;
    procedure ControlButton_Click(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
end

constructor TAEDBGrid.Create(AOwner: TComponent);
var Menu: TPopupMenu;
    Item: TMenuItem;
begin
    inherited Create(AOwner);

    ControlButton := TButton.Create(nil);
    ControlButton.Caption := '...';
    ControlButton.Font.Style := Self.Font.Style + [fsBold];
    ControlButton.Top := Self.Top + 1;
    ControlButton.Left := Self.Left + 1;
    ControlButton.Height := 19;
    ControlButton.Width := 17;
    ControlButton.Parent := Self.Parent;
    ControlButton.OnClick := ControlButton_Click;

    Menu := TPopupMenu.Create(ControlButton);
    Item := TMenuItem.Create(Menu);
    Item.Caption := 'Select Columns';
    Item.OnClick := ControlButton_SelectColumns;
    Menu.Items.Add(Item);
    Item := TMenuItem.Create(Menu);
    Item.Caption := 'Export to Excel';
    Item.OnClick := ControlButton_ExportToExcel;
    Item.Visible := False;
    Menu.Items.Add(Item);
    ControlButton.PopupMenu := Menu;
end;

destructor TAEDBGrid.Destroy;
begin
    ControlButton.Free;

    inherited Destroy;
end;

procedure TAEDBGrid.ControlButton_Click(Sender: TObject);
var Position: TPoint;
begin
  if GetCursorPos(Position) then ControlButton.PopupMenu.Popup(Position.X, Position.Y);
end;

问题是,在我创建 ControlButton 的那一刻,Self.Top、Self.Left 属性为 0,而 Self.Parent 为 nil。所以我的按钮没有父级并且不可见。

我应该重写什么方法来创建已经分配了 Grid 父级的按钮?我试过AfterConstruction,同样的问题。

我发现的最佳替代方法是覆盖 SetFocus 并检查 not Assigned(ControlButton),但它仅在用户进入网格时创建按钮。

谢谢。

【问题讨论】:

  • 就个人而言,我会从馈入网格的数据集的 AfterScroll 事件开始,因为它决定了网格的活动行。
  • 感谢 Martyn,但我想在我的 Grid 后代上对其进行编程,因此我不必在每个网格上都复制它。在网格的构造函数中,您将替换其 Datasource.Dataset 的 AfterScroll 以创建该按钮并回调原始事件处理程序?。似乎有点太复杂了。

标签: delphi vcl delphi-10.4.2


【解决方案1】:

如果你想让网格成为按钮的父级,那么你应该写

ControlButton.Parent := Self; //(and not Self.Parent)

因为你在网格的构造函数中。

【讨论】:

    【解决方案2】:

    你可以尝试覆盖Loaded方法:

    protected
    { Protected declarations }
    procedure Loaded; override;
    

    并在里面初始化你的子控件。

    【讨论】:

    • 感谢 Miroslav,但我在 cmets 上遵循了 Tom 的建议,现在它可以在构造函数本身上正常工作。我分配了错误的父母。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 2018-09-25
    • 1970-01-01
    • 2014-08-30
    • 2014-01-11
    • 1970-01-01
    • 2013-08-23
    相关资源
    最近更新 更多