3

を使用しTGridPanelていくつかのパネルを保持しています。設計時に、グリッド パネルを 1 行 5 列に設定しました。

このコードを使用してグリッドにパネルを追加できます。これはうまく機能します。

procedure TForm6.AddPanelToGrid(const ACaption: string);
var
  pnl: TPanel;
begin
  pnl := TPanel.Create(gpOne);
  pnl.Caption := ACaption;
  pnl.Parent := gpOne;
  pnl.Name := 'pnlName' + ACaption;
  pnl.OnClick := gpOne.OnClick;
  pnl.ParentBackground := false;
  pnl.ParentColor := false;
  pnl.Color := clLime;
  pnl.Font.Size := 14;
  gpOne.ControlCollection.AddControl(pnl);
  pnl.Height := pnl.Width;
end;

私がやりたいことは、TPanelクリックしたときにグリッドから a を削除することです (これが、上記のコードでオンクリック ハンドラーをグリッド パネルのハンドラーに設定した理由です)。

そのクリックハンドラーでこれを行います。これはほとんど機能します:

procedure TForm6.gpOneClick(Sender: TObject);
begin
  if not (sender is TPanel) then exit;

  gpOne.ControlCollection.RemoveControl(Sender as TPanel);
  (Sender as TPanel).Free;

  gpOne.UpdateControlsColumn( 0 );  <<<-------
  gpOne.UpdateControlsRow(0);

  gpOne.Refresh();
end;

パラメータを使用するUpdateControlColumn()と、グリッド内のパネルの順序が変更されます (1 番目と 2 番目の場所が入れ替わります)。

これを回避するには、列の idex をパネルのタグ プロパティに追加し、それを UpdateControlColumn() に渡します。これは機能しますが、パネルが削除されると、より高いタグ番号は無効になります - パネルは列を移動しました。

OnClickでは、ハンドラー 内からパネルが入っている列を取得するにはどうすればよいでしょうか?

私はDelphi 10.1 Berlinを使用しています-それが違いを生む場合。

これをテストするために、新しいプロジェクトを開始し、 を追加しTGridPanel、1 行と 5 つの等幅の列を持つように設定しました。6 つTButtonのコントロールを追加OnClickし、次のコードを使用してそれぞれのハンドラーを作成しました。

AddPanelToGrid('One');  // changing the string for each button.

いくつかのボタンをクリックしてパネルを追加し、パネルをクリックして削除します。

4

1 に答える 1

1

TCustomGridPanel には と のペアの便利な関数がCellIndexToCell()ありますCellToCellIndexが、これらは公開されていないため、TGridPanel から直接アクセスすることはできません。

それらを利用可能にするにTGridPanelは、以下のように新たに宣言します。

type
  TGridPanel = class(Vcl.ExtCtrls.TGridPanel)  // add this
  end;                                         // -"-
  TForm27 = class(TForm)
    Button1: TButton;
    gpOne: TGridPanel;
    ...
  end;

次に、行と列に変数rと変数を追加し、呼び出しを追加して、の引数として使用します。cCellIndexToCell()cUpdateControlsColumn

procedure TForm27.gpOneClick(Sender: TObject);
var
  r, c: integer;
begin
  if not (sender is TPanel) then exit;

  gpOne.CellIndexToCell(gpOne.ControlCollection.IndexOf(Sender as TPanel), c, r); // add this

  gpOne.ControlCollection.RemoveControl(Sender as TPanel);
  (Sender as TPanel).Free;

  gpOne.UpdateControlsColumn( c );  // <<<-------
  gpOne.UpdateControlsRow(0);

  gpOne.Refresh();
end;

パネルの解放に関しては、Remy Lebeau のアドバイスに従ってください。(私は彼のコメントに気づきました)。


まだ行っていない場合は、TFlowPanelとそのFlowStyleプロパティも確認することをお勧めします。TflowPanel複数の行を使用する場合、削除後の並べ替えはより予測可能ですが、もちろん必要なものによって異なります。

于 2016-08-16T16:50:40.943 に答える