Tgridpanelでセルをクリックします
-
26-10-2019 - |
質問
私は持っています TGridPanel
フォームで、クリックされた特定の「セル」にコントロールを追加したい。
私は十分にポイントを十分に得ることができます:
procedure TForm1.GridPanel1DblClick(Sender: TObject);
var
P : TPoint;
InsCol, InsRow : Integer;
begin
P := (Sender as TGridPanel).ScreenToClient(Mouse.CursorPos);
if (Sender as TGridPanel).ControlAtPos(P) = nil then
begin
InsCol := ???;
InsRow := ???;
(Sender as TGridPanel).ControlCollection.AddControl(MyControl, InsCol, InsRow)
end;
end;
私はおそらく必要ありません if ControlAtPos(P) = nil then
ラインですが、私はすでにセルにあるセルにコントロールを挿入していないことを確認したいと思います。
それで...インスコールと廃止を取得するためにどのコードを使用しますか?私は上下しています TGridPanel
と TControlCollection
クラスコードと、マウス座標から列または行の値を提供するものは何も見つかりません。彼らは他のもの以外に使用する関連イベントのようにも見えません OnDblClick()
.
どんな助けも大歓迎です。
編集:混乱を避けるために、変数の結果をMyControlに変更しました。
解決
procedure TForm1.GridPanel1Click(Sender: TObject);
var
P: TPoint;
R: TRect;
InsCol, InsRow : Integer;
begin
P := (Sender as TGridPanel).ScreenToClient(Mouse.CursorPos);
for InsCol := 0 to GridPanel1.ColumnCollection.Count - 1 do
begin
for InsRow := 0 to GridPanel1.RowCollection.Count - 1 do
begin
R:= GridPanel1.CellRect[InsCol,InsRow];
if PointInRect(P,R) then
begin
ShowMessage (Format('InsCol = %s and InsRow = %s.',[IntToStr(InsCol), IntToStr(InsRow)]))
end;
end;
end;
end;
function TForm1.PointInRect(aPoint: TPoint; aRect: TRect): boolean;
begin
begin
Result:=(aPoint.X >= aRect.Left ) and
(aPoint.X < aRect.Right ) and
(aPoint.Y >= aRect.Top ) and
(aPoint.Y < aRect.Bottom);
end;
end;
他のヒント
Ravaut123のアプローチの最適化は次のとおりです(より大きなグリッドの場合、はるかに高速にする必要があります)。この関数は、TpointのX/Yグリッドの場所を返します。ユーザーが有効な列をクリックしたが有効な行をクリックした場合、有効な列情報は引き続き返され、同じことが行にも当てはまります。したがって、「すべてか何もない」(有効なセルまたは無効なセル)ではありません。この関数は、グリッドが「通常」であると想定しています(すべての列は最初の列と同じ行の高さを持ち、同様にすべての行は最初の行と同じ列幅を持っています)。グリッドが規則的でない場合、Ravaut123のソリューションがより良い選択です。
// APoint is a point in local coordinates for which you want to find the cell location.
function FindCellInGridPanel(AGridPanel: TGridPanel; const APoint: TPoint): TPoint;
var
ICol, IRow : Integer;
R : TRect;
begin
Result.X := -1;
Result.Y := -1;
for ICol := 0 to AGridPanel.ColumnCollection.Count - 1 do
begin
R := AGridPanel.CellRect[ICol, 0];
if (APoint.X >= R.Left) and (APoint.X <= R.Right) then
begin
Result.X := ICol;
Break;
end;
end;
for IRow := 0 to AGridPanel.RowCollection.Count - 1 do
begin
R := AGridPanel.CellRect[0, IRow];
if (APoint.Y >= R.Top) and (APoint.Y <= R.Bottom) then
begin
Result.Y := IRow;
Break;
end;
end;
end;
所属していません StackOverflow