TVirtualTreeview 编辑器如何工作?

Ash*_*lar 3 delphi virtualtreeview

我正在 Delphi 中探索 Virtual Treeview 并运行了一个示例程序,其中通过按 F2 来调用编辑器,开始编辑过程使用 Virtualtreeview 中的内置编辑器(无附加编辑组件)。文本发生了变化,但当我单击不同的节点时,它立即变回了原始文本。

这让我探索了 VirtualTrees.pas 中的源代码,以研究编辑过程是如何工作的。一切似乎都归结为TBaseVirtualTree.doedit. 我已经检查了每个步骤,但不确定列中的编辑框究竟是什么操作。

procedure TBaseVirtualTree.DoEdit;

begin
  Application.CancelHint;
  StopTimer(ScrollTimer);
  StopTimer(EditTimer);
  DoStateChange([], [tsEditPending]);
  if Assigned(FFocusedNode) and not (vsDisabled in FFocusedNode.States) and
    not (toReadOnly in FOptions.FMiscOptions) and (FEditLink = nil) then
  begin
    FEditLink := DoCreateEditor(FFocusedNode, FEditColumn);
    if Assigned(FEditLink) then
    begin
      DoStateChange([tsEditing], [tsDrawSelecting, tsDrawSelPending, tsToggleFocusedSelection, tsOLEDragPending,
        tsOLEDragging, tsClearPending, tsDrawSelPending, tsScrollPending, tsScrolling, tsMouseCheckPending]);
      ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions,
        not (toDisableAutoscrollOnEdit in FOptions.AutoOptions));
      if FEditLink.PrepareEdit(Self, FFocusedNode, FEditColumn) then
      begin
        UpdateEditBounds;
        // Node needs repaint because the selection rectangle and static text must disappear.
        InvalidateNode(FFocusedNode);
        if not FEditLink.BeginEdit then
          DoStateChange([], [tsEditing]);
      end
      else
        DoStateChange([], [tsEditing]);
      if not (tsEditing in FStates) then
        FEditLink := nil;
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

所以我的问题是 VirtualTree 如何将实际的键盘输入放置在 node.text 中,以及如何将编辑结果放入数据记录中?

kob*_*bik 6

您需要处理OnNewText事件,例如:

procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; Text: UnicodeString);
var
  data: TMyData;
begin
  data := TMyData(Sender.GetNodeData(Node)^);
  if Assigned(data) then
  begin
    if Column = 0 then
      data.Caption := Text
    else
      data.Value := Text;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

在编辑器中编辑文本后立即调用此事件。

编辑器是通过IVTEditLink接口实现的。FEditLink.BeginEdit开始编辑过程。

内置编辑器TStringEditLink实现IVTEditLink,如果你想知道它是如何工作的,你需要研究代码。

如果您需要使用自己的编辑器(如组合框类的编辑器),你将需要实现IVTEditLink和回报您EditLinkOnCreateEditor事件中。

VST 的 Demo 目录中有一些很好的属性编辑器示例,它们展示了如何实现您自己的编辑器。