2011-08-10 21 views
1

検索ダイアログを使用してstring gridでテキスト検索を行う方法はありますか?私はテキストを見つけて、テキストが見つかったときにそれを背景として強調表示する必要があります。Delphi:検索ダイアログと文字列グリッド

ありがとうございます!

+0

このうちどの部分に助けが必要ですか?問題がグリッド内のテキストを検索しているか、それを強調する方法ですか? –

+0

@David Heffernan、どのようにそれを強調するには?お願いします。 – maxfax

+0

文字列グリッド内のセルを選択することによって強調表示することができます。アンドレアスの答えもそれをカバーしています。 –

答えて

8

このように:

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; 
label 
    TheEnd; 
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; 
     goto TheEnd; 
     end; 
     inc(X); 
    end; 
    inc(Y); 
    X := StringGrid1.FixedCols; 
    end; 
TheEnd: 
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); 
    goto TheEnd; 
    end; 

を入力してください。しかし、これは検索ダイアログからフォーカスを奪うので、ユーザーは次の一致を選択するためにReturnキーを押すことができなくなり、迷惑になる可能性があります。

+2

コードに 'goto'の使用を詮索するための+1。グリッド上で反復処理を行っていたプロダクションコードでは、グリッドをフラット化したいくつかの列挙子を記述し、 'for 'ループでそれを歩くことができます。 –

+3

私はデビッドの熱狂者のアイディアが好きです。そして、私はStringGridをまったく使用したくないのではなく、VirtualTreeViewコントロールを使用してグリッドとして使用し、グリッドに表示されるドキュメントの内容をモデルオブジェクトに含めるようにしたいと思います。 memento/command-patternを実装し、アンドゥ/リドゥ機能を備えています。また、私はポニーを実装するだろう。 –

+0

@Andreas Rejbrand、素晴らしい、完全な答え! 1000あなたに感謝! – maxfax