5

があり、TableLayoutPanelクリックしたセルにコントロールを追加したいと思います。

問題は、実行時にクリックしたセルを特定できないことです。

クリックされているセルを特定するにはどうすればよいですか?

4

4 に答える 4

11

GetColumnWidthsおよびメソッドを使用しGetRowHeightsて、セルの行と列のインデックスを計算できます。

Point? GetRowColIndex(TableLayoutPanel tlp, Point point)
{
    if (point.X > tlp.Width || point.Y > tlp.Height)
        return null;

    int w = tlp.Width;
    int h = tlp.Height;
    int[] widths = tlp.GetColumnWidths();

    int i;
    for (i = widths.Length - 1; i >= 0 && point.X < w; i--)
        w -= widths[i];
    int col = i + 1;

    int[] heights = tlp.GetRowHeights();
    for (i = heights.Length - 1; i >= 0 && point.Y < h; i--)
        h -= heights[i];

    int row = i + 1;

    return new Point(col, row);
}

使用法:

private void tableLayoutPanel1_Click(object sender, EventArgs e)
{
    var cellPos = GetRowColIndex(
        tableLayoutPanel1,
        tableLayoutPanel1.PointToClient(Cursor.Position));
}

ただし、セルにコントロールがまだ含まれていない場合にのみ、クリックイベントが発生することに注意してください。

于 2013-03-16T13:41:04.447 に答える
4

これは私のために働いた:

public TableLayoutPanel tableLayoutPanel { get; set; }

private void Form_Load(object sender, EventArgs e)
{
    foreach (Panel space in this.tableLayoutPanel.Controls)
    {
        space.MouseClick += new MouseEventHandler(clickOnSpace);
    }
}

public void clickOnSpace(object sender, MouseEventArgs e)
{

    MessageBox.Show("Cell chosen: (" + 
                     tableLayoutPanel.GetRow((Panel)sender) + ", " + 
                     tableLayoutPanel.GetColumn((Panel)sender) + ")");
}

tableLayoutPanelはグローバルに宣言されているため、各関数に渡さなくても使用できます。また、tableLayoutPanelとその中の各Panelの両方が、他の場所で完全にプログラムで作成されます(私のフォーム[デザイン]は完全に空白です)。

于 2016-08-08T20:35:32.327 に答える
2

私の答えは上記の@MohammadDehghanの答えに基づいていますが、いくつかの利点があります。

  • 垂直スクロールが考慮されるようになりました
  • i=0列は正しい順序になっています(ではなくから始まりますi=length)。つまり、幅または高さが異なる列が正しい順序で処理されます。

コードの更新バージョンは次のとおりです。

public Point? GetIndex(TableLayoutPanel tlp, Point point)
{
    // Method adapted from: stackoverflow.com/a/15449969
    if (point.X > tlp.Width || point.Y > tlp.Height)
        return null;

    int w = 0, h = 0;
    int[] widths = tlp.GetColumnWidths(), heights = tlp.GetRowHeights();

    int i;
    for (i = 0; i < widths.Length && point.X > w; i++)
    {
        w += widths[i];
    }
    int col = i - 1;

    for (i = 0; i < heights.Length && point.Y + tlp.VerticalScroll.Value > h; i++)
    {
        h += heights[i];
    }
    int row = i - 1;

    return new Point(col, row);
}
于 2017-01-30T12:03:59.540 に答える
0

Nickの答えは、セルにさまざまな種類のコントロールを含むTableLayoutPanelsに対して汎用にすることができることを除いて、最良の解決策でした。明示的な「パネル」タイプを「コントロール」に変更するだけです。

public TableLayoutPanel tableLayoutPanel { get; set; }

private void Form_Load(object sender, EventArgs e)
{
    foreach (Control c in this.tableLayoutPanel.Controls)
    {
        c.MouseClick += new MouseEventHandler(ClickOnTableLayoutPanel);
    }
}

public void ClickOnTableLayoutPanel(object sender, MouseEventArgs e)
{

    MessageBox.Show("Cell chosen: (" + 
                     tableLayoutPanel.GetRow((Control)sender) + ", " + 
                     tableLayoutPanel.GetColumn((Control)sender) + ")");
}

これはうまく機能し、クリックされたセルを見つけるために座標計算を行う必要はありません。

于 2019-07-06T23:35:08.133 に答える