【问题标题】:How to underline or highlight a part of node caption如何下划线或突出显示节点标题的一部分
【发布时间】:2015-08-13 09:51:25
【问题描述】:

我想在我的 virtualtreeview 中实现搜索功能。我想在节点中突出显示或下划线搜索到的单词。

我该怎么做? 谢谢

【问题讨论】:

    标签: delphi virtualtreeview


    【解决方案1】:

    我会为OnDrawText 事件编写一个处理程序,因为它是(此时)您将获得节点文本、将要呈现该文本的矩形以及准备好的画布的唯一事件(此时)对于这样的渲染。这两个任务都有更合适的事件(例如 OnBeforeCellPaintOnAfterItemErase 用于文本背景突出显示,OnAfterCellPaintOnAfterItemPaint 用于文本下划线),只是它们都没有提供文本渲染特定参数作为 OnDrawText一个。

    如果您的节点不是多行的,并且您不关心文本对齐、阅读方向或字符串缩短,那么您的任务可能就像以下示例之一一样简单。

    1。匹配文字背景颜色

    procedure TForm1.VirtualTreeDrawText(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
      Node: PVirtualNode; Column: TColumnIndex; const Text: string; const CellRect: TRect;
      var DefaultDraw: Boolean);
    var
      BackMode: Integer;
    begin
      // if the just rendered node's Text starts with the text written in a TEdit control
      // called Edit, then...
      if StartsText(Edit.Text, Text) then
      begin
        // store the current background mode; we need to use Windows API here because the
        // VT internally uses it (so the TCanvas object gets out of sync with the DC)
        BackMode := GetBkMode(TargetCanvas.Handle);
        // setup the color and draw the rectangle in a width of the matching text
        TargetCanvas.Brush.Color := clYellow;
        TargetCanvas.FillRect(Rect(
          CellRect.Left,
          CellRect.Top + 1,
          CellRect.Left + TargetCanvas.TextWidth(Copy(Text, 1, Length(Edit.Text))),
          CellRect.Bottom - 1)
        );
        // restore the original background mode (as it likely was modified by setting the
        // brush color)
        SetBkMode(TargetCanvas.Handle, BackMode);
      end;
    end;
    

    视觉输出示例:

    2。匹配文字下划线

    procedure TForm1.VirtualTreeDrawText(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
      Node: PVirtualNode; Column: TColumnIndex; const Text: string; const CellRect: TRect;
      var DefaultDraw: Boolean);
    begin
      // if the just rendered node's Text starts with the text written in a TEdit control
      // called Edit, then...
      if StartsText(Edit.Text, Text) then
      begin
        TargetCanvas.Pen.Color := clRed;
        TargetCanvas.MoveTo(CellRect.Left, CellRect.Bottom - 2);
        TargetCanvas.LineTo(
          CellRect.Left + TargetCanvas.TextWidth(Copy(Text, 1, Length(Edit.Text))),
          CellRect.Bottom - 2
        );
      end;
    end;
    

    还有一个视觉输出示例:

    在实际代码中,我建议预先计算那些突出显示的形状,并在OnDrawText 事件中仅绘制,但优化我会留给你;我认为重点是事件本身。

    【讨论】:

    • 太棒了...非常感谢。
    • 感谢 TLama。我也会在几周内尝试代码。
    【解决方案2】:

    小改动。注意if。

    var
      BackMode: integer;
    begin
      inherited;
    
      // if the just rendered node's Text starts with the text written in a TEdit control
      // called Edit, then...
      if StartsText(Sender.SearchBuffer, Text) and (Node = Sender.FocusedNode) then
      begin
        TargetCanvas.Pen.Color := clRed;
        TargetCanvas.MoveTo(CellRect.Left, CellRect.Bottom - 2);
        TargetCanvas.LineTo(
          CellRect.Left + TargetCanvas.TextWidth(Copy(Text, 1, Length(Sender.SearchBuffer))),
          CellRect.Bottom - 2
        );
      end;
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-02
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多