我有一个TableLayoutPanel
,我想在我点击的单元格中添加一个控件。
问题是我无法确定我在运行时点击的单元格。
如何确定点击的单元格?
答案 0 :(得分:8)
您可以使用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));
}
但请注意,如果单元格尚未包含控件,则仅引发click事件。
答案 1 :(得分:3)
这对我有用:
[TestMethod]
public void TestContainer()
{
var container = MyContainer.Container.GetInstance<DbContext>();
var parentContext = container.GetInstance<MyContext>();
var childContext = container.GetInstance<MyContext>();
// This call will fail
container.Verify();
}
请注意,我的tableLayoutPanel是全局声明的,因此我可以使用它而不必将其传递给每个函数。另外,tableLayoutPanel和其中的每个Panel都是以编程方式在其他地方创建的(我的表单[design]完全是空白的。)
答案 2 :(得分:2)
我的回答基于@Mohammad Dehghan上面的答案,但有几个好处:
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);
}
答案 3 :(得分:0)
Nick的答案是最好的解决方案,除了可以使TableLayoutPanels通用(在单元格中包含不同类型的控件)。只需将显式的“ Panel”类型更改为“ Control”即可:
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) + ")");
}
这很好用,不需要做坐标数学来找到被单击的单元格。