如何水平居中多个对象在一个给定的容器



我花了一整天的时间试图解决这个问题,但没有令人满意的结果。

我必须居中一些标签在他们的容器(面板)。如果只有一个标签,这将是一件轻而易举的事情,但生活并不容易,我必须编写一个方法来居中多个对象,并克服两个问题:

  1. 可以是1到8之间的任意数量的标签,我不知道在设计时有多少。
  2. 我必须能够指定标签之间的确切间距。

如果没有2,这不会这么难,经过一番思考,我想出了这个:

private void panel1_Resize(object sender, EventArgs e)
{
    int position = 1;
    foreach (Label l in panel1.Controls)
    {
        CenterToParent(l, panel1.Controls.Count, position);
        position++;
    }
}
private static void CenterToParent(Label lbl, int qty, int pos)
{
    lbl.SetBounds((lbl.Parent.Bounds.Width - lbl.Width) * pos / (qty + 1),
                    lbl.Location.Y, lbl.Width, lbl.Height);
}

但是这样标签之间的空间将随着面板宽度的变化而变化,并且这个间隙必须是固定的大小。这也是为什么我不能简单地使用TableLayoutPanel。

PS:如果你会如此善良,这将是非常开明的,如果你使centertopparent方法工作,如果我不知道对象类型(只是它确实有相同的属性)。我有一种感觉,我将在不久的将来需要它,我不知道如何做到这一点。

至少对于您的第二个问题,只需将Label lbl更改为Control ctrl。它可以任意控制并将其集中在父节点上,假设它是父节点。您不妨检查一下是否有这种情况。

更新:

我又考虑了一下你的问题。首先,如果面板上有任何非Label控件,您的应用程序将在foreach循环期间崩溃。更改为foreach (Control ctrl in panel1.Controls)。这也使用了我对你第二个问题的原始答案。

你的基本问题是,给定一定数量的控件,它们必须水平居中于父控件,并且间隔均匀。它的总宽度是:(control1.Width + offset) + (control2.Width + offset) ... (controlN.Width + offset) - offset。如果(Parent.Width / 2) - (TotalWidth / 2)的x坐标(startX)。既然知道了x坐标,就可以开始像这样布局控件了:

control1.Left = startX;
control2.Left = control1.Right + offset
controlN.Left = control(N-1).Right + offset

实际代码可能像这样:

const int Offset = 8; // for example
int totalWidth = panel1.Controls.Cast<Control>().Aggregate(0, (value, ctrl) => value + ctrl.Width + Offset);
for (int index = 0; index < panel1.Controls.Count; index++)
{
    Control current = panel1.Controls[index];
    if (index == 0)
    {
        current.Left = startX;
    }
    else
    {
        current.Left = panel1.Controls[index-1].Right + Offset;
    }
}

我承认没有测试过这个,但也许你会从这里得到它的工作。好运。

相关内容

  • 没有找到相关文章

最新更新