【问题标题】:Lazarus (Delphi/FPC): constructor in class helper is not executedLazarus (Delphi/FPC):类助手中的构造函数未执行
【发布时间】:2016-07-03 17:26:43
【问题描述】:

我正在尝试找到一个通用** 解决方案,通过某些功能(例如每个节点的工具提示)来扩展内置 Treeview/TreeNode。所以首先我派生了一个TExtendedTreeNode = class(TTreeNode) 并添加了一个似乎工作正常的相应属性 - 我可以为每个节点添加具有不同工具提示的 TExtendedTreeNodes。

对于下一步,我想使用 TTreeView.OnMouseMove 事件来显示相应的 ToolTip,但是以通用**方式扩展此功能的最佳解决方案是什么?

我的想法是使用class helper for TTreeView

type
  TTreeViewExtension = class helper for TTreeView
  private
    procedure ShowNodeToolTips(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  public
    constructor Create(AnOwner: TComponent);
  end;

...

constructor TTreeViewExtension.Create(AnOwner: TComponent);

begin
  inherited Create(AnOwner);

  ShowMessage('TTreeViewExtension.Create');

  self.OnMouseMove := @self.ShowNodeToolTips;
end;

代码编译时没有警告或错误,但在我的表单中创建树视图时不会执行此构造函数。

是的,我在表单单元和扩展单元中都使用了advancedrecords in objfpc mode - 为了使用类助手:

{$mode objfpc}{$H+}
{$modeswitch advancedrecords+}

** “通用”的意思是,我想至少将 Lazarus IDE 中的集成控件用于 TreeView 控件,但使用扩展功能而无需编写两次代码。

【问题讨论】:

  • 创建 TTreeView 的后代并覆盖其受保护的方法procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  • 是的,如果可以以向前的方式完成,请不要滥用类助手之类的巴洛克式结构。我不确定类助手是否允许覆盖方法。班级助手是一个拐杖,而不是瑞士军队。
  • @Marco:我不了解 FPC,但在 Delphi 中,类助手不能覆盖虚拟或动态方法,原因很明显。事实上,它们是一个拐杖,最初是为了让 TObject 和其他一些类与相应的 C# 类兼容。它们现在被使用得更多了,但它们仍然是一个拐杖。
  • 对,在FPC里好像完全一样。

标签: delphi treeview lazarus freepascal


【解决方案1】:

您为什么不使用已经可用的OnHint 事件来显示这些工具提示。 TTreeView.OnHint 事件已经返回对鼠标光标下方树节点的引用,因此从节点读取自定义提示(工具提示)应该没有任何问题。

如果提示可以在一行文本中显示,您只需更改此事件方法中公开的Hint 变量的值。

您可以通过将事件方法返回的Node 常量类型转换为TExtendedTreeNode 类来轻松地从Extended TreeNode 中读取此类值。 不要忘记检查有问题的节点是否确实属于正确的类。

procedure TForm1.TreeView1Hint(Sender: TObject; const Node: TTreeNode;
  var Hint: string);
begin
  //Check to see if the node beneath the cursor is the extended node
  if Node is TExtendedTreeNode then
    //if it is change the hint text to the custom hint stored in the
    //node itself
    Hint := TExtendedTreeNode(Node).CustomHint
  //Else change the hint to empty string so no hintbox will be shown
  else Hint := '';
end;

如果您不希望显示任何提示文本并以不同的方式显示您的信息,您只需将 Hint 值设置为空字符串。

procedure TForm1.TreeView1Hint(Sender: TObject; const Node: TTreeNode;
  var Hint: string);
begin
  //Set Hint to empty string in order to not show any hint box
  Hint := '';
  //Do some other code instead if you like
  MessageBeep(0);
end;

【讨论】:

  • 感谢您的建议,但这并不能解决我的主要问题,即在我的应用程序中将其集成到由 IDE 的表单设计器创建的所有现有和未来的 TreeView 中,而无需编写额外的代码。好吧,也许我没有解释清楚——我的英语不是最好的。
  • 在这种情况下,我认为最好的解决方案是用额外的代码扩展 TTreeView 组件,并将所有现有的 TTreeView 组件替换为扩展的组件。
  • 看起来 Lazarus 没有 TTreeview.OnHint 事件 - 我猜它是在较新版本的 Delphi 中创建的,Lazarus 将在以后的版本中支持它......只有一个 TTreeview..OnShowHint 事件 - 这个比 MouseMove 更好,因为它仅在需要新提示时调用,但我必须以与上述相同的方式确定当前节点。我刚刚开始开发一个可以在表单设计器中注册为可视控件的 IDE 组件。现在我知道这至少是可能的,而且这确实是最好的解决方案。
猜你喜欢
  • 2017-01-21
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
相关资源
最近更新 更多