Delphi: найти диалоговое окно и сетку строк

Есть ли способ выполнить текстовый поиск в string grid с помощью диалогового окна поиска? Мне нужно найти текст и выделить его фон, как обычно, когда текст найден.

Спасибо!


person maxfax    schedule 10.08.2011    source источник
comment
В какой части этого вам нужна помощь? Проблема в поиске текста внутри сетки или в том, как его выделить?   -  person David Heffernan    schedule 10.08.2011
comment
@ Дэвид Хеффернан, как это выделить? Пожалуйста.   -  person maxfax    schedule 10.08.2011
comment
Вы можете выделить ячейку в сетке строк, выбрав ее. Ответ Андреаса также охватывает это.   -  person Warren P    schedule 10.08.2011


Ответы (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», чтобы выбрать следующее совпадение, что может раздражать.

person Andreas Rejbrand    schedule 10.08.2011
comment
+1 за скрытое использование goto в коде. В производственном коде, где вы много перебирали сетки, вы вполне можете написать несколько перечислителей, которые сглаживают сетку, чтобы вы могли пройти по ней с помощью цикла for in. - person David Heffernan; 10.08.2011
comment
Мне нравится идея счетчика Дэвида. И в производстве у меня возникло бы искушение вообще не использовать StringGrid, а использовать элемент управления VirtualTreeView, используемый в качестве сетки, и иметь объект модели, содержащий содержимое моего документа, который отображается в сетке и который реализует шаблон сувенира / команды и имеет функции отмены / повтора. Кроме того, я бы реализовал пони. - person Warren P; 10.08.2011
comment
Один вопрос, что такое StringGrid1.Components[0]? :) - person maxfax; 10.08.2011
comment
@maxfax: это редактор на месте. Когда вы редактируете текст в одной из ячеек, всплывает редактор (это похоже на TEdit без рамки) и располагается над ячейкой. Поскольку этот элемент управления редактором является дочерним элементом сетки строк, а также единственным дочерним элементом (по крайней мере, первым), вы можете получить к нему доступ через массив Components. - person Andreas Rejbrand; 10.08.2011
comment
+1; написано, что у меня нет компонентов - индекс списка выходит за пределы (0). Что добавить? Спасибо. - person maxfax; 10.08.2011
comment
@maxfax: встроенный редактор есть только в том случае, если ячейки доступны для редактирования (конечно!). У вас должен быть goEditing in Options, и редактор должен быть создан. (Это автоматически, так как мой код выше делает EditorMode := true.) Если вы не хотите, чтобы ячейки редактировались, вам нужно будет выполнить пользовательское рисование, чтобы выбрать (выделить) только искомый текст, а не всю ячейку. . - person Andreas Rejbrand; 10.08.2011
comment
Извините, goEditing отключен. Ваша помощь действительно хороша. Спасибо! - person maxfax; 10.08.2011
comment
Итак, если GoEditing включен, как предотвратить редактирование пользователем (изменение текста ячеек)? Только чтение? - person maxfax; 10.08.2011
comment
@maxfax: Да, я думаю, вы могли бы сделать встроенный редактор доступным только для чтения, но чем больше трюков вы применяете, тем менее надежным становится код ... ' - person Andreas Rejbrand; 10.08.2011
comment
Почему не Exit; вместо goto TheEnd; ? - person nurettin; 29.06.2018
comment
@nurettin: Нет веской причины. Скорее всего, я добавил это goto в то время, когда у меня был код после метки. Но потом я удалил этот код. Я обновлю ответ. - person Andreas Rejbrand; 29.06.2018
comment
почему бы не поставить код после метки в finally :-P - person nurettin; 29.06.2018
comment
@nurettin: Во многих случаях это имеет смысл, особенно если вам нужно защитить ресурсы или какое-то состояние (от исключений, раннего выхода и т. д.), но не все. Но я, конечно, не могу вспомнить, как выглядел код с самого начала, так как этому А восемь лет! (Кроме того, иногда я пытаюсь немного поиграть и немного повеселиться, так что это может быть небольшой юмористический аспект.) - person Andreas Rejbrand; 29.06.2018
comment
@AndreasRejbrand Кстати, спасибо за всю работу над algosim, это очень интересно, я пытался изучить его несколько лет назад. Тоже интересно посмотреть исходники. Если только вы не хотите сделать его коммерческим. - person nurettin; 29.06.2018
comment
@nurettin: Спасибо! Собственно, сейчас я переписываю AlgoSim с нуля (и делаю это уже год или два). Новая версия будет с открытым исходным кодом! Но я думаю, что он не будет выпущен до следующего года или около того. - person Andreas Rejbrand; 29.06.2018