Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何确定在TableLayoutPanel中单击的单元格?_C#_Winforms_Tablelayoutpanel - Fatal编程技术网

C# 如何确定在TableLayoutPanel中单击的单元格?

C# 如何确定在TableLayoutPanel中单击的单元格?,c#,winforms,tablelayoutpanel,C#,Winforms,Tablelayoutpanel,我有一个TableLayoutPanel,我想在单击的单元格中添加一个控件 问题是我无法确定在运行时单击的单元格 如何确定单击的单元格?您可以使用和方法计算单元格的行和列索引: Point? GetRowColIndex(TableLayoutPanel tlp, Point point) { if (point.X > tlp.Width || point.Y > tlp.Height) return null; int w = tlp.Width

我有一个
TableLayoutPanel
,我想在单击的单元格中添加一个控件

问题是我无法确定在运行时单击的单元格

如何确定单击的单元格?

您可以使用和方法计算单元格的行和列索引:

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);
}
但请注意,只有当单元格中尚未包含控件时,才会引发click事件。

这对我很有效:

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和其中的每个面板都是在其他地方完全以编程方式创建的(我的表单[设计]完全为空)。

我的答案基于上面的答案,但有两个优点:

  • 现在它考虑了垂直滚动
  • 列的顺序正确(从
    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);
}
公共点?GetIndex(TableLayoutPanel tlp,Point点)
{
//方法改编自:stackoverflow.com/a/15449969
if(点X>tlp.宽度| |点Y>tlp.高度)
返回null;
int w=0,h=0;
int[]宽度=tlp.GetColumnWidths(),高度=tlp.GetRowHeights();
int i;
对于(i=0;iw;i++)
{
w+=宽度[i];
}
int col=i-1;
对于(i=0;ih;i++)
{
h+=高度[i];
}
int行=i-1;
返回新点(列、行);
}

尼克的答案是最好的解决方案,除了它可以成为单元格中包含不同控件的TableLayoutPanel的通用解决方案。只需将显式“Panel”类型更改为“Control”:


这非常有效,不需要进行坐标计算就可以找到单击的单元格。

我找不到GetColumnWidths和GetColumnWidthsGetRowHeights@AymanSharaf别担心。它们在Visual Studio Intellisence中不可见。它们有
[Browsable(false)]
属性,但它们是存在的,如果你使用我的代码,你会发现它们会起作用。这与2006年2月发布的答案类似。
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);
}
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) + ")");
}