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) + ")");
}