2

我对这个社区很陌生,我有这个以编程方式添加控件的应用程序。我想将所有添加的控件居中,就像选择它们并在 Visual Studio 上按中心一样。不,我不想把每一个放在一边。这是我用来获取所有控件的代码:

    private void GetAllControl(Control c, List<Control> list)
    {
        //gets all controls and saves them to a list
        foreach (Control control in c.Controls)
        {
            list.Add(control);
        }
    }

    //And then call it like this

        List<Control> list = new List<Control>();
        GetAllControl(PNL_custom, list);
        foreach (Play_panel m in list)
        {
            //And here I want to insert that center code
        }

提前致谢,

VB理论

4

6 回答 6

2

“不,我不想把每一个都放在一边。”

所以你想“对齐”控件列表?...如:

格式 --> 对齐 --> 居中

格式 --> 对齐 --> 中间

如果是,则计算每个控件的中心并将 X、Y 坐标相加,以便计算“平均”点(质心)。现在您可以迭代控件并将其用作对齐 X 或 Y 值,具体取决于您想要的方向。只需减去一半的宽度或高度并保留另一个值。

就像是:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        List<Control> list = new List<Control>();
        GetAllControl(PNL_custom, list);
        CenterControls(list, Direction.Vertical);
    }

    public enum Direction
    {
        Vertical,
        Horizontal
    }

    private void CenterControls(List<Control> controls, Direction direction)
    {
        if (controls.Count > 1)
        {
            int xSum = 0;
            int ySum = 0;
            Point center;
            foreach (Control ctl in controls)
            {
                center = new Point(ctl.Location.X + ctl.Width / 2, ctl.Location.Y + ctl.Height / 2);
                xSum = xSum + center.X;
                ySum = ySum + center.Y;
            }
            Point average = new Point(xSum / controls.Count, ySum / controls.Count);
            foreach (Control ctl in controls)
            {
                switch (direction)
                {
                    case Direction.Vertical:
                        ctl.Location = new Point(average.X - ctl.Width / 2, ctl.Location.Y);
                        break;

                    case Direction.Horizontal:
                        ctl.Location = new Point(ctl.Location.X, average.Y - ctl.Height / 2);
                        break;
                }
            }
        }
    }

    private void GetAllControl(Control c, List<Control> list)
    {
        //gets all controls and saves them to a list
        foreach (Control control in c.Controls)
        {
            list.Add(control);
        }
    }
}
于 2013-05-10T12:44:44.707 回答
2

以下是如何将控件作为GROUP居中。除了我们计算组的质心必须移动多远才能成为父控件的中心之外,它几乎与以前相同。然后我们遍历所有控件并将它们的位置偏移这么多。这将它们全部居中,同时保持它们相对于彼此的位置:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        List<Control> list = new List<Control>();
        GetAllControl(PNL_custom, list);
        CenterControlsAsGroup(list, Direction.Both); // center group in the center of the parent
    }

    public enum Direction
    {
        Vertical,
        Horizontal,
        Both
    }

    private void CenterControlsAsGroup(List<Control> controls, Direction direction)
    {
        if (controls.Count > 1)
        {
            int xSum = 0;
            int ySum = 0;
            Point center;
            foreach (Control ctl in controls)
            {
                center = new Point(ctl.Location.X + ctl.Width / 2, ctl.Location.Y + ctl.Height / 2);
                xSum = xSum + center.X;
                ySum = ySum + center.Y;
            }
            Point average = new Point(xSum / controls.Count, ySum / controls.Count);

            center = new Point(controls[0].Parent.Width / 2, controls[0].Parent.Height / 2);
            int xOffset = center.X - average.X;
            int yOffset = center.Y - average.Y;

            foreach (Control ctl in controls)
            {
                switch (direction)
                {
                    case Direction.Vertical:
                        ctl.Location = new Point(ctl.Location.X + xOffset, ctl.Location.Y);
                        break;

                    case Direction.Horizontal:
                        ctl.Location = new Point(ctl.Location.X, ctl.Location.Y + yOffset);
                        break;

                    case Direction.Both:
                        ctl.Location = new Point(ctl.Location.X + xOffset, ctl.Location.Y + yOffset);
                        break;
                }
            }
        }
    }

    private void GetAllControl(Control c, List<Control> list)
    {
        //gets all controls and saves them to a list
        foreach (Control control in c.Controls)
        {
            list.Add(control);
        }
    }

}
于 2013-05-10T22:03:06.847 回答
1

获取控件容器(另一个控件或窗体)的宽度和高度。控件的坐标是以像素为单位的距离,相对于其容器的左上角(即 (0,0))。因此,您所要做的就是将控件的x坐标设置为(form width - control width) / 2. 身高也是一样。

于 2013-05-10T12:20:39.153 回答
0

您的所有控件都将被添加到一个容器(很可能是表单)中,尽管它们可以很容易地放在一个组框等中。

要将它们在容器内居中对齐,您需要做一些数学运算并自己定位它们:)

在将控件置于容器中心之前,您需要找到容器的中点。这将是容器的宽度/2:容器的高度/2。

我将使用一个名为 cmdButton1 的控件来突出显示 - 您将需要遍历控件列表并依次对所有控件执行此操作。

int midParentX = cmdButton1.Parent.width / 2;
int midParentX = cmdButton1.Parent.height / 2;

然后你可以在这个中点放置一个控件:

cmdButton1.Location.X = midParentX;
cmdButton1.Location.Y = midParentY;

但是,您的控件(在我的示例中为 cmdButton)锚定在 (0,0) 处,即控件的左上角,因此我们需要将其向后和向上移动其宽度和高度的一半

cmdButton1.Location.X -= (cmdButton1.width / 2);
cmdButton1.Location.Y -= (cmdButton1.height / 2);

为了更相关:

foreach (Play_panel m in list)
{
    int pX = m.Parent.width;
    int pY = m.Parent.height;

    m.Location.X = (pX / 2) - (m.width / 2);
    m.Location.Y = (pY / 2) - (m.height / 2);
}
于 2013-05-10T12:31:49.120 回答
0

所以我这样做了:

    public enum ArrangeOrientation : int {
        None,
        Horizonatal,
        Vertical,
        HorizontalGrid,
        VerticalGrid,
        TopLeftGrid,
        TopRightGrid,
        BottomLeftGrid,
        BottomRightGrid
    }

    private void ArrangeButtons(List<Control> controls, List<Control> parents, ArrangeOrientation orientation, double shrinkFactor = 1d) {
        if(controls == null) return;
        if(parents == null) parents = new List<Control>();
        List<Control> childs = new List<Control>();
        Control parent = null;

        foreach(Control ctrl in controls) {
            if(parent == null && !parents.Contains(ctrl.Parent)) {
                parents.Add(ctrl.Parent);
                parent = ctrl.Parent;
            }
            if(parent == ctrl.Parent)
                childs.Add(ctrl);
        }
        if(parent != null && childs.Count > 0) {
            ArrangeControlsToGridLayout(childs, orientation, shrinkFactor);
            ArrangeButtons(controls, parents, orientation, shrinkFactor);
        }
    }

    private void ArrangeControlsToGridLayout(List<Control> controls, ArrangeOrientation orientation, double shrinkFactor = 1d) {
        // do nothing if nothing set
        if(orientation == ArrangeOrientation.None) return;
        if(shrinkFactor == 0d|| shrinkFactor > 1d) shrinkFactor = 1d;

        // buffer controls in separate list to avoid manipulating parameter
        List<Control> ctrl = new List<Control>(controls.ToArray());
        // remove invisible controls
        int j = 0;
        while(j < ctrl.Count) {
            if(!ctrl[j].Visible) ctrl.RemoveAt(j);
            else j++;
        }

        // loop arrangement
        int count = ctrl.Count;
        int xDelta, yDelta, xOffs, yOffs, y, x, columns, rows, parentWidth, parentHeight, xShrinkOffs, yShrinkOffs;
        if(count >= 1) {

            // parents size
            parentWidth = ctrl[0].Parent.Width;
            parentHeight = ctrl[0].Parent.Height;
            // shrink factor offset
            parentWidth = Convert.ToInt32(parentWidth * shrinkFactor);
            parentHeight = Convert.ToInt32(parentHeight * shrinkFactor);
            // shrink factor offset
            xShrinkOffs = Convert.ToInt32((ctrl[0].Parent.Width - parentWidth) / 2d);
            yShrinkOffs = Convert.ToInt32((ctrl[0].Parent.Height - parentHeight) / 2d);

            // calculate columns rows grid layout                            
            if(orientation == ArrangeOrientation.Horizonatal) {
                rows = 1;
                columns = count;
            }
            else if(orientation == ArrangeOrientation.Vertical) {
                rows = count;
                columns = 1;
            }
            else if(orientation == ArrangeOrientation.TopLeftGrid
                || orientation == ArrangeOrientation.TopRightGrid
                || orientation == ArrangeOrientation.BottomLeftGrid
                || orientation == ArrangeOrientation.BottomRightGrid) {
                rows = 1;
                columns = count;
            }
            else {
                rows = Convert.ToInt32(Math.Floor(Math.Sqrt(count)));
                if(Math.Sqrt(count) % 1d != 0d) rows++;
                columns = count / rows + (count % rows != 0 ? 1 : 0);
            }
            if(orientation == ArrangeOrientation.HorizontalGrid) {
                int swap = columns;
                columns = rows;
                rows = columns;
            }

            // calculate position offsets, grid distance
            xDelta = parentWidth / count;
            yDelta = parentHeight / count;
            xOffs = xDelta / 2;
            yOffs = yDelta / 2;                
            if(orientation == ArrangeOrientation.TopLeftGrid) {                                                     
            }
            else if(orientation == ArrangeOrientation.TopRightGrid) {
                xOffs = parentWidth - xOffs;
                xDelta = -xDelta;
            }
            else if(orientation == ArrangeOrientation.BottomLeftGrid) {
                yOffs = parentHeight - yOffs;
                yDelta = -yDelta;
            }
            else if(orientation == ArrangeOrientation.BottomRightGrid) {
                xOffs = parentWidth - xOffs;
                yOffs = parentHeight - yOffs;
                xDelta = -xDelta;
                yDelta = -yDelta;
            }
            else {
                xDelta = parentWidth / columns;
                yDelta = parentHeight / rows;
                xOffs = xDelta / 2;
                yOffs = yDelta / 2;
            }

            // fit controls in grid layout               
            Point pRoot = new Point(/*ctrl[0].Parent.Location.X + */xOffs, /*ctrl[0].Parent.Location.Y + */yOffs);
            y = 0; x = 0;
            for(int i = 0; i < count; i++) {

                if(orientation == ArrangeOrientation.VerticalGrid) {
                    // actual x/y - points zero based index
                    y = Convert.ToInt32(Math.Floor((double)i % rows));
                    // next row? zero based index
                    if(i % rows == 0 && i != 0) x++;
                }
                else {
                    // actual x/y - points zero based index
                    x = Convert.ToInt32(Math.Floor((double)i % columns));
                    // next row? zero based index
                    if(i % columns == 0 && i != 0) y++;
                    if(orientation == ArrangeOrientation.TopLeftGrid
                        || orientation == ArrangeOrientation.TopRightGrid
                        || orientation == ArrangeOrientation.BottomLeftGrid
                        || orientation == ArrangeOrientation.BottomRightGrid)
                        y = x;
                }                   // assign controls to grid
                ctrl[i].Location = new Point(pRoot.X + x * xDelta - ctrl[i].Size.Width / 2 + xShrinkOffs, pRoot.Y + y * yDelta - ctrl[i].Size.Height / 2 + yShrinkOffs);

            }
        }
    }
于 2016-07-07T10:47:30.727 回答
0

当有多个控件时,上面的代码将所有控件放在一起。

我要做的就是将所有控件集中在一个面板内,但将它们彼此相邻放置,而不是将一个放在另一个之上。

这是我修改后的代码(仅供参考,这将使控件集中在 1 行而不是多行):

   public enum Direction
    {
        Vertical,
        Horizontal,
        Both
    }

    public void CenterControls(List<Control> controls, Direction direction)
    {
        if (controls.Count > 1)
        {
             int controls_sum_width = 0;
            int controls_seperation = 20;
            int parentwidth = 0;               

            Point center;
            foreach (Control ctl in controls)
            {
                 controls_sum_width = controls_sum_width + ctl.Width + controls_seperation;
            }

            Point Container_center = new Point(controls[0].Parent.Width / 2, controls[0].Parent.Height / 2);
            parentwidth = controls[0].Parent.Width;
            int xoffset = (parentwidth - controls_sum_width) / 2;


            int Location_X = 0;
            foreach (Control ctl in controls)
            {
                center = new Point( ctl.Width / 2,  ctl.Height / 2);
                int yOffset = Container_center.Y - center.Y;
                switch (direction)
                {
                    case Direction.Vertical:
                        ctl.Location = new Point(ctl.Location.X + xoffset, ctl.Location.Y);
                        break;

                    case Direction.Horizontal:
                        ctl.Location = new Point(ctl.Location.X, yOffset);
                        break;

                    case Direction.Both:
                        ctl.Location = new Point(Location_X + xoffset,  yOffset);
                        break;
                }
                Location_X = Location_X + ctl.Width+ controls_seperation;
            }
        }
        else
        {
            Point parent_center;
            Point center;
            parent_center = new Point(controls[0].Parent.Width / 2, controls[0].Parent.Height / 2);
            center = new Point(controls[0].Location.X + controls[0].Width / 2, controls[0].Location.Y + controls[0].Height / 2);
            int xOffset = parent_center.X - center.X;
            int yOffset = parent_center.Y - center.Y;
            switch (direction)
            {
                case Direction.Vertical:
                    controls[0].Location = new Point(controls[0].Location.X + xOffset, controls[0].Location.Y);
                    break;

                case Direction.Horizontal:
                    controls[0].Location = new Point(controls[0].Location.X, controls[0].Location.Y + yOffset);
                    break;

                case Direction.Both:
                    controls[0].Location = new Point(controls[0].Location.X + xOffset, controls[0].Location.Y + yOffset);
                    break;
            }
        }
    }

    public void GetAllControl(Control c, List<Control> list)
    {
        //gets all controls and saves them to a list
        foreach (Control control in c.Controls)
        {
            list.Add(control);
        }
    }
于 2017-12-29T22:10:16.917 回答