将行动态添加到TableLayoutPanel会在不同的行号(位置)上显示
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将行动态添加到TableLayoutPanel会在不同的行号(位置)上显示相关的知识,希望对你有一定的参考价值。
我正在尝试通过单击按钮将TextBox动态添加到TableLayoutPanel。通过单击鼠标选择一行。在选择行之后,单击按钮会在所选行号上插入TextBox。 问题是在不同选择的行上正确地[文本框3或4次后,单击以下按钮将开始在随机行上显示文本框,即使调试显示正确的行号也是如此。需要帮助请,这里是完整的代码:
public partial class Form1 : Form
{
private TableLayoutPanel _tableLayout;
private int _selectedRow = -1;
public Form1()
{
InitializeComponent();
var button = new Button()
{
Text = "Add Text"
};
button.MouseClick += AddText;
this.Controls.Add(button);
_tableLayout = new TableLayoutPanel()
{
Dock = DockStyle.Fill,
AutoScroll = true,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
CellBorderStyle = TableLayoutPanelCellBorderStyle.Single
};
_tableLayout.MouseClick += SelectRow;
this.Controls.Add(_tableLayout);
}
private void SelectRow(object sender, MouseEventArgs e)
{
_selectedRow = GetRowColIndex(_tableLayout, e.Location).Value.Y;
}
private void AddText(object sender, MouseEventArgs e)
{
_tableLayout.ColumnStyles.Add(new ColumnStyle() { SizeType = SizeType.AutoSize });
_tableLayout.RowStyles.Add(new RowStyle() { SizeType = SizeType.AutoSize });
_tableLayout.Controls.Add(new TextBox(), 0, _selectedRow);
}
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);
}
}
您可以在代码中使用相同的逻辑,也可以使用已知的方法,从e.CellBounds
事件中的
CellPaint参数检索单击的单元格边界。
这里的例子,从TLP的MouseClick
事件中获取鼠标位置,并使用中的e.CellBounds.Contains(currentPointerLocation)
方法在单元格的边界包含鼠标指针并更新几个具有当前坐标的标签,存储在2个字段中,以方便显示:Point currentPointerLocation = Point.Empty;
Rectangle currentCellBounds = Rectangle.Empty;
Point currentCell = Point.Empty;
private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
if (e.CellBounds.Contains(currentPointerLocation)) {
currentCellBounds = e.CellBounds;
currentCell = new Point(e.Row, e.Column);
e.Graphics.FillRectangle(Brushes.Red, e.CellBounds);
}
else {
using (var brush = new SolidBrush(tableLayoutPanel1.BackColor)) {
e.Graphics.FillRectangle(brush, e.CellBounds);
}
}
}
private void tableLayoutPanel1_MouseClick(object sender, MouseEventArgs e)
{
currentPointerLocation = e.Location;
this.tableLayoutPanel1.Invalidate();
this.tableLayoutPanel1.Update();
lblCurrentCell.Text = currentCell.ToString();
lblCellBounds.Text = currentCellBounds.ToString();
}
有了这些值,在将控件添加到使用鼠标指针选定的单元格时,确定当前单元格的坐标并使用它们就更加容易。例如,使用按钮(
btnAddControl
)和ContextMenuStrip向TableLayoutPanel添加不同的控件:
private void btnAddControl_Click(object sender, EventArgs e) { tableLayoutPanel1.Controls.Add(new TextBox() { Multiline = true, Text = "TextBox from Button", Dock = DockStyle.Fill }, currentCell.Y, currentCell.X); } // Each ToolStripMenuItem sub-item subscribes to the event using this handler private void contextTLPMenu_Clicked(object sender, EventArgs e) { Control ctl = null; switch ((sender as ToolStripMenuItem).Text) { case "TextBox": ctl = new TextBox() { Multiline = true, Text = "TextBox from ContextMenu" }; break; case "Button": ctl = new Button() { Text = "A Button", ForeColor = Color.White }; break; case "Panel": ctl = new Panel() { BackColor = Color.LightGreen }; break; default: break; } if (ctl != null) { ctl.Dock = DockStyle.Fill; tableLayoutPanel1.Controls.Add(ctl, currentCell.Y, currentCell.X); } }
视觉结果:
以上是关于将行动态添加到TableLayoutPanel会在不同的行号(位置)上显示的主要内容,如果未能解决你的问题,请参考以下文章