StringGridにコンボボックスを入れるには


scorpos  2003-09-02 20:57:37  No: 4552

こんにちは。

質問はタイトルの通りで
StringGridの固定列にコンボボックスを表示させたいのです。
Gridの行は動的です。
セル間はEnterで移動したいと思っています。
その時コンボボックスが入っているセルに来た時は
コンボボックスにフォーカスを移動し、
またコンボボックスの選択が終わりEnterで次のセルへ。

このようなことは可能なのでしょうか?
どなたかアドバイスをお願い致します。

開発環境
  Delphi5
  Window2000


LupinⅢ  URL  2003-09-02 22:20:50  No: 4553

スマートな方法ではないのですが、コンボボックスを一つ配置してVisible := Falseにしておき、  StringGridのOnSelectCellでVisibleをTrueにして位置を計算して移動させればそれっぽく見えます。そしてフォーカスがExitするときに再びVisibleをFalseにすればいいと思います。


scorpos  2003-09-02 22:53:37  No: 4554

LupinⅢさん
アドバイスありがとうございます。

このやり方だとフォーカスのあるセルだけにコンボボックスが見える
ということですよね。
常に指定の列にコンボボックスを表示させておくのは難しいのでしょうか?


masayan  2003-09-02 23:04:56  No: 4555

自分も同様のプログラムを作成しましたが、全てのセルにコンボボックスを表示するのは難しかったのでそのセルに移動したときだけコンボボックスを表示するようにしました。
質問の内容と違うかもしれませんが、参考までに概略を説明します。

①フォームにグリッド(Grid)とコンボボックス(Combo)をそれぞれ1つ配置します。Combo.VisibleをFalseにします。

②GridのOnClickイベントにComboの表示制御を記述します。
  begin
    // 3列目に移動したときにコンボを表示する
    if Grid.Col = 2 then
    begin
      // セルの内容をComboに設定
      Combo.Text := Grid.Cells[Grid.Col,Grid.Row];
      // Comboの位置と大きさをセルにあわせる
      // Grid.CellRectを使ってComboのLeft,Top等を設定します。
      Combo.Visible := True;  // コンボ表示
      ActiveControl := Combo; // フォーカスをコンボへ
    end
    else
      Combo.Visible := False;
    
    OldCol := Grid.Col;
    OldRow := Grid.Row;
    // OldCol,OldRowはフォームのPrivateで宣言(Integer変数)

  end;

③ComboのOnExitに入力完了処理を記述する

  begin
    Grid.Cells[OldCol,OldRow] := Combo.Text;
    Grid.Col := OldCol + 1; // 次のセルへ
    Combo.Visible := False; // コンボ非表示
  end;

④GirdとComboのOnKeyDownにEnterによりフォーカス移動処理を記述する。

  Grid:
    EnterキーでGrid.Col + 1,必要であれば右端で折り返し/行追加。
               Combo更新のためGridOnClickを呼び出す。
  Combo:
    EnterキーでフォーカスをGridへ

以上です。


にしの  2003-09-02 23:32:11  No: 4556

オーナードローでコンボボックスを描画してしまうのも手です。
リソースも喰いませんし。


scorpos  2003-09-03 01:18:06  No: 4557

masayanさん、にしのさん
ありがとうございます。

masayanさんのやり方を試していますが
セルの位置を上手く取ることができなくて苦戦中です。
そしてコンボボックスも表示してくれない(T_T)
これはいろいろいじって試してみます。

質問の内容が変わってしまうのですが
これはActiveFormでも使えるのでしょうか?


masayan  2003-09-05 18:55:33  No: 4558

scorposさん がんばってください。

もう解決されているかもしれませんが、以下が実際に動くサンプルソースです。参考にしてください。
(概略でちょっと複雑に説明しすぎたみたいです。すいません。)
ActiveFormですが、実際にやったことがないのでわかりませんが、たぶん大丈夫だと思います。

{ EVENT : Grid OnClick }
procedure TForm1.GridClick(Sender: TObject);
var
  ARect : TRect;
begin
  if Grid.Col = 2 then
  begin
    ARect := Grid.CellRect(Grid.Col,Grid.Row);

    Combo.Top := ARect.Top + Grid.Top;
    Combo.Left := ARect.Left + Grid.Left;
    Combo.Width := ARect.Right - ARect.Left;

    Combo.Text := Grid.Cells[Grid.Col,Grid.Row];

    Combo.Visible := True;
    ActiveControl := Combo;
  end
  else
  begin
    Combo.Visible := False;
  end;
end;

{ EVENT : Grid OnKeyDown }
procedure TForm1.GridKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    if Grid.Col < (Grid.ColCount - 1) then
      Grid.Col := Grid.Col + 1
    else
    begin
      if Grid.Row < (Grid.RowCount - 1) then
      begin
        Grid.Row := Grid.Row + 1;
        Grid.Col := 1;
      end;
    end;
  end;
end;

{ EVENT : Combo OnExit }
procedure TForm1.ComboExit(Sender: TObject);
begin
  Grid.Cells[Grid.Col,Grid.Row] := Combo.Text;
  Combo.Visible := False;
end;

{ EVENT : Combo OnKeyDown }
procedure TForm1.ComboKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    ActiveControl := Grid;
    Grid.Col := Grid.Col + 1;
  end
  else if Key = VK_LEFT then
  begin
    ActiveControl := Grid;
    Grid.Col := Grid.Col - 1;
  end;
end;


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加