我正在尝试制作一个面板,它可以承载动态添加的控件。有两个注意事项:
我看到了一些以一种形式提出的中心化动态控件的解决方案,并基于以下原因拒绝了这些解决方案:
我想知道我是否缺少了一些功能,可以帮助我处理增长/收缩事件而不创建我自己的TableLayoutPanel变体?
编辑:
以下是功能草案:

发布于 2019-02-07 01:31:32
下面是一个复制您描述的行为的示例。
它使用一个承载多个TableLayoutPanel的FlowLayoutPanels。
一个重要的细节是子FlowLayoutPanels的锚定:它们需要锚定到顶部底部的:这将导致面板位于TableLayoutPanel行的中心。
注意,在表单构造函数中,一个RowStyles被删除。这也是非常重要的:TLP (它是非常古怪的家伙),即使你只有一列(或一列,同样的东西),也会保留2 RowStyles。第二种样式将应用于您添加的第一排,只适用于第一种,而不是其他:这会使布局变得一团糟。
另一个异常,它没有提供移除行的方法,所以我做了一个。它的功能,但基本,需要扩展,包括进一步的验证。
请参阅有关当前功能的图形示例。如果在实现其他方面需要帮助,请留下评论。
若要构建此控件,请将以下控件添加到窗体(此处,称为FLPTest1):)
Dock.Bottom。右击和SendToBack(),tlp1),集(这里称为TableLayoutPanel集: )AutoScroll = true,AutoSize = true,AutoSizeMode = GrowAndShrink,Dock.Fillflp1),(这里称为FlowLayoutPanel ),位于TableLayoutPanel中。实际上,这并不是必要的,只是对于这个示例代码Top, Bottom <= --这是!important,如果没有它,布局将无法正常工作:它允许FLP在TLP行中居中,AutoSize = true,AutoSizeMode = GrowAndShrinkbtnAddControl) )btnRemoveControl) )chkRandom) (称为CheckBox )

using System.Drawing;
using System.Linq;
using System.Windows.Forms;
public partial class TLPTest1 : Form
{
public TLPTest1()
{
InitializeComponent();
tlp1.RowStyles.RemoveAt(1);
}
private void TLPTest1_Load(object sender, EventArgs e)
{
PictureBox pBox = new PictureBox() {
Anchor = AnchorStyles.None,
BackColor = Color.Orange,
MinimumSize = new Size(125, 125),
Size = new Size(125, 125),
};
flp1.Controls.Add(pBox);
tlp1.Controls.Add(flp1);
}
Random rnd = new Random();
Size[] sizes = new Size[] { new Size(75, 75), new Size(100, 100), new Size(125, 125)};
Color[] colors = new Color[] { Color.Red, Color.LightGreen, Color.YellowGreen, Color.SteelBlue };
Control selectedObject = null;
private void btnAddControl_Click(object sender, EventArgs e)
{
Size size = new Size(125, 125);
if (chkRandom.Checked) size = sizes[rnd.Next(sizes.Length)];
var pBox = new PictureBox() {
Anchor = AnchorStyles.None,
BackColor = colors[rnd.Next(colors.Length)],
MinimumSize = size,
Size = size
};
bool drawborder = false;
// Just for testing - use standard delegates instead of Lambdas in real code
pBox.MouseEnter += (s, evt) => { drawborder = true; pBox.Invalidate(); };
pBox.MouseLeave += (s, evt) => { drawborder = false; pBox.Invalidate(); };
pBox.MouseDown += (s, evt) => { selectedObject = pBox; pBox.Invalidate(); };
pBox.Paint += (s, evt) => { if (drawborder) {
ControlPaint.DrawBorder(evt.Graphics, pBox.ClientRectangle,
Color.White, ButtonBorderStyle.Solid);
}
};
var ctl = tlp1.GetControlFromPosition(0, tlp1.RowCount - 1);
int overallWith = ctl.Controls.OfType<Control>().Sum(c => c.Width + c.Margin.Left + c.Margin.Right);
overallWith += (ctl.Margin.Right + ctl.Margin.Left);
if ((overallWith + pBox.Size.Width + pBox.Margin.Left + pBox.Margin.Right) >= tlp1.Width) {
var flp = new FlowLayoutPanel() {
Anchor = AnchorStyles.Top | AnchorStyles.Bottom,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
};
flp.Controls.Add(pBox);
tlp1.SuspendLayout();
tlp1.RowCount += 1;
tlp1.Controls.Add(flp, 0, tlp1.RowCount - 1);
tlp1.ResumeLayout(true);
}
else {
ctl.Controls.Add(pBox);
}
}
private void btnRemoveControl_Click(object sender, EventArgs e)
{
if (selectedObject is null) return;
Control parent = selectedObject.Parent;
selectedObject.Dispose();
if (parent?.Controls.Count == 0) {
TLPRemoveRow(tlp1, parent);
parent.Dispose();
}
}
private void TLPRemoveRow(TableLayoutPanel tlp, Control control)
{
int ctlPosition = tlp.GetRow(control);
if (ctlPosition < tlp.RowCount - 1) {
for (int i = ctlPosition; i < tlp.RowCount - 1; i++) {
tlp.SetRow(tlp.GetControlFromPosition(0, i + 1), i);
}
}
tlp.RowCount -= 1;
}
}https://stackoverflow.com/questions/54542104
复制相似问题