【问题标题】:Delphi: Find Dialog & String GridDelphi:查找对话框和字符串网格
【发布时间】:2011-10-23 22:31:14
【问题描述】:

有没有办法使用查找对话框在string grid 中进行文本搜索?我需要找到一个文本并像通常在找到文本时一样突出显示它的背景。

谢谢!

【问题讨论】:

  • 您需要帮助的哪一部分?是在网格内搜索文本的问题,还是如何突出显示它?
  • @David Heffernan,如何突出显示它?请。
  • 您可以通过选择它来突出显示字符串网格中的一个单元格。 Andreas 的回答也涵盖了这一点。

标签: delphi text find highlighting tstringgrid


【解决方案1】:

像这样:

procedure TForm1.FormClick(Sender: TObject);
begin
  FindDialog1.Execute(Handle)
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FindDialog1.Options := [frDown, frHideWholeWord, frHideUpDown];
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
var
  CurX, CurY, GridWidth, GridHeight: integer;
  X, Y: integer;
  TargetText: string;
  CellText: string;
  i: integer;
  GridRect: TGridRect;
begin
  CurX := StringGrid1.Selection.Left + 1;
  CurY := StringGrid1.Selection.Top;
  GridWidth := StringGrid1.ColCount;
  GridHeight := StringGrid1.RowCount;
  Y := CurY;
  X := CurX;
  if frMatchCase in FindDialog1.Options then
    TargetText := FindDialog1.FindText
  else
    TargetText := AnsiLowerCase(FindDialog1.FindText);
  while Y < GridHeight do
  begin
    while X < GridWidth do
    begin
      if frMatchCase in FindDialog1.Options then
        CellText := StringGrid1.Cells[X, Y]
      else
        CellText := AnsiLowerCase(StringGrid1.Cells[X, Y]);
      i := Pos(TargetText, CellText) ;
      if i > 0 then
      begin
        GridRect.Left := X;
        GridRect.Right := X;
        GridRect.Top := Y;
        GridRect.Bottom := Y;
        StringGrid1.Selection := GridRect;
        Exit;
      end;
      inc(X);
    end;
    inc(Y);
    X := StringGrid1.FixedCols;
  end;
end;

此代码可以轻松扩展以支持向后搜索(“向上”),您可能还希望实现“匹配整个单词”功能。

也许您只想选择匹配的文本,而不是整个单元格?然后做

  if i > 0 then
  begin
    GridRect.Left := X;
    GridRect.Right := X;
    GridRect.Top := Y;
    GridRect.Bottom := Y;
    StringGrid1.Selection := GridRect;
    GetParentForm(StringGrid1).SetFocus;
    StringGrid1.SetFocus;
    StringGrid1.EditorMode := true;
    TCustomEdit(StringGrid1.Components[0]).SelStart := i - 1;
    TCustomEdit(StringGrid1.Components[0]).SelLength := length(TargetText);
    Exit;
  end;

相反。但这会从查找对话框中窃取焦点,因此用户将无法按 Return 键选择下一个匹配项,这可能很烦人。

【讨论】:

  • +1 用于在代码中偷偷使用goto。在您对网格进行大量迭代的生产代码中,您可能会编写一些使网格变平的枚举器,以便您可以使用for in 循环遍历它。
  • 我喜欢 David 的枚举数想法。在生产中,我会倾向于不使用 StringGrid,而是使用 VirtualTreeView 控件,用作网格,并让模型对象包含我的文档的内容,它显示在网格中,并且实现备忘录/命令模式并具有撤消/重做功能。另外,我会实现一个小马。
  • 一个问题,什么是StringGrid1.Components[0]? :)
  • @maxfax:那是就地编辑器。当您在其中一个单元格中编辑文本时,会弹出编辑器(它就像一个没有边框的TEdit)并位于单元格上方。由于此编辑器控件是字符串网格的子项,也是 only 子项(至少是第一个子项),因此您可以通过 Components 数组访问它。
  • @maxfax:如果单元格是可编辑的(当然!),则只有一个就地编辑器。您必须拥有goEditing in Options,并且必须创建编辑器。 (这是自动的,因为我上面的代码是EditorMode := true。)如果您不希望单元格可编辑,则必须进行自定义绘画以仅选择(突出显示)寻找的文本,而不是整个单元格...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2011-11-09
相关资源
最近更新 更多