在 c# winforms 中的控件内水平和垂直对齐动态添加的控件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19192740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:20:57  来源:igfitidea点击:

Align dynamically added controls horizontally and vertically within a control in c# winforms

c#winformsdynamic

提问by Lyndon Broz Tonelete

I have this program that dynamically adds pictureboxes referring to the number of president in the database. How do i put them inside the groupbox and align the pictureboxes inside the groupbox? And the groupbox should stretch if the pictureboxes are many.

我有这个程序,可以动态添加参考数据库中总统人数的图片框。我如何将它们放在分组框内并对齐分组框内的图片框?如果图片框很多,分组框应该拉伸。

I have this codes now :

我现在有这个代码:

    private void Form1_Load(object sender, EventArgs e)
    {
        conn.Open();

        try
        {
            cmd = new SqlCommand("SELECT COUNT(Position) FROM TableVote WHERE Position='" + "President" + "'", conn);
            Int32 PresCount = (Int32)cmd.ExecuteScalar();

            TxtPresCount.Text = PresCount.ToString();

            for (int i = 0; i < PresCount; ++i)
            {
                GroupBox PresGB = new GroupBox();
                {
                    PresGB.Size = new Size(491, 152);
                    PresGB.Location = new Point(12, 12);
                    PresGB.Text = "President";
                    this.Controls.Add(PresGB);
                    PresGB.SendToBack();

                    PictureBox PresPB = new PictureBox();
                    PresPB.Location = new Point(80 + (150 * i) + 20, 50);
                    PresPB.Size = new Size(75, 75);
                    PresPB.BorderStyle = BorderStyle.Fixed3D;
                    PresPB.ImageLocation = "imgPath";
                    this.Controls.Add(PresPB);
                    PresPB.BringToFront();
                };
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            conn.Close();
        }
    }

I would want the pictureboxes to be inside the groupbox and align it inside.

我希望图片框位于 groupbox 内并将其对齐。

采纳答案by pescolino

Maybe the FlowLayoutPanelcontrol already does what you are trying to do. Just create your picture boxes and add them to a FlowLayoutPanelinstead of a GroupBox.

也许FlowLayoutPanel控件已经做了你想要做的事情。只需创建您的图片框并将它们添加到 aFlowLayoutPanel而不是GroupBox.

FlowLayoutPanelautomatically arranges controls in rows and/or columns depending on the value of its FlowDirectionproperty. Set myFlowLayoutPanel.FlowDirection = FlowDirection.TopDownto get a vertical arranged list.

FlowLayoutPanel根据其FlowDirection属性的值自动按行和/或列排列控件。设置myFlowLayoutPanel.FlowDirection = FlowDirection.TopDown以获取垂直排列的列表。

If you don't want multiple rows or columns set the WrapContentsproperty to false. You can also set the AutoScrollproperty to true to automatically get scrollbars if the controls don't fit.

如果您不想要多行或多列,请将WrapContents属性设置为 false。AutoScroll如果控件不适合,您还可以将该属性设置为 true 以自动获取滚动条。

If you prefer to have the border of a GroupBoxyou can still put the FlowLayoutPanelinto a GroupBox.

如果您更喜欢 a 的边框,GroupBox您仍然可以将FlowLayoutPanela 放入GroupBox.

To adjust the space between the picture boxes you can use the Marginproperty.

要调整图片框之间的空间,您可以使用该Margin属性。

This gives you a lot of control over the layout and you don't need to calculate the control positions. Also, if the size of the FlowLayoutPanelchanges everything is rearranged automatically.

这使您可以对布局进行大量控制,并且无需计算控制位置。此外,如果FlowLayoutPanel更改的大小一切都会自动重新排列。

UPDATE:

更新:

I have a few comments on your code:

我对您的代码有几点意见:

  1. The curly braces make this look like the syntax of an object initializer - but it isn't.

    GroupBox PresGB = new GroupBox(); // this line ends with a semicolon
    {
        // therefore this is just a block of code not related to new GroupBox()
    };
    

    You should remove the curly braces.

  2. The creation of the group box is inside the loop. I doubt that you want a new group box for each picture box. This is the reason why you only see a single picture. Each new group box hides all the previous ones.

  3. You add the picture boxes to the form instead of the group box.

  4. You use "cryptic" names. PresGBand PresPBare very likely to be swapped accidentally. Abbreviations are usually a bad choice for names.

  5. You don't need to call SendToBackor BringToFrontsince you don't want the controls to overlap anyway.

  6. I don't think GroupBoxis a good choice. Of course you can make it bigger if the number of pictures increases but you are limited by the screen and you don't get scollbars if the picture boxes don't fit. Use a FlowLayoutPanel. It has all the "magic" that you are looking for.

  1. 花括号使这看起来像对象初始值设定项的语法 - 但事实并非如此。

    GroupBox PresGB = new GroupBox(); // this line ends with a semicolon
    {
        // therefore this is just a block of code not related to new GroupBox()
    };
    

    您应该删除花括号。

  2. 组框的创建在循环内。我怀疑您是否希望每个图片框都有一个新的组框。这就是为什么你只能看到一张图片的原因。每个新的分组框都会隐藏所有以前的分组框。

  3. 您将图片框添加到窗体而不是组框。

  4. 你使用“神秘”的名字。PresGB并且PresPB很可能会被意外交换。缩写通常是名称的错误选择。

  5. 您不需要调用SendToBack或者BringToFront因为您不希望控件重叠。

  6. 我认为GroupBox不是一个好的选择。当然,如果图片数量增加,您可以将其放大,但是您受到屏幕的限制,如果图片框不适合,您将无法获得scollbars。使用一个FlowLayoutPanel. 它具有您正在寻找的所有“魔法”。

Replace your for loop with this piece of code:

用这段代码替换你的 for 循环:

var panel = new FlowLayoutPanel();
panel.SuspendLayout(); // don't calculate the layout before all picture boxes are added
panel.Size = new Size(491, 152);
panel.Location = new Point(12, 12);
panel.BorderStyle = BorderStyle.Fixed3D;
panel.FlowDirection = FlowDirection.LeftToRight;
panel.AutoScroll = true; // automatically add scrollbars if needed
panel.WrapContents = false; // all picture boxes in a single row
this.Controls.Add(panel);

for (int i = 0; i < PresCount; ++i)
{
    var pictureBox = new PictureBox();
    // the location is calculated by the FlowLayoutPanel
    pictureBox.Size = new Size(75, 75);
    pictureBox.BorderStyle = BorderStyle.FixedSingle;
    pictureBox.ImageLocation = "imgPath";
    panel.Controls.Add(pictureBox);
}

panel.ResumeLayout(); 

回答by Zippit

You can always drop a control on your form, do what you want to do then look at the designer generated code to see how the designer does it (in the "Designer.cs" file). Behind the scenes it is loading all controls and setting all properties via code.

您始终可以在表单上放置一个控件,执行您想要执行的操作,然后查看设计器生成的代码以了解设计器是如何执行的(在“Designer.cs”文件中)。在幕后,它通过代码加载所有控件并设置所有属性。

That being said.

话虽如此。

Keep in mind that once you put your picturebox inside the groupbox all location coordinate are in relation to the groupbox. So "0,0" is the upper-left corner of the groupbox, not the form.

请记住,一旦您将图片框放入 groupbox 中,所有位置坐标都与 groupbox 相关。所以“0,0”是分组框的左上角,而不是表单。

To anchor your picturebox use the following code (this is just a straight copy-paste from my designer generated code, so you can clean it up a bit):

要锚定您的图片框,请使用以下代码(这只是我的设计师生成的代码的直接复制粘贴,因此您可以稍微清理一下):

this.PresPB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
        | System.Windows.Forms.AnchorStyles.Left) 
        | System.Windows.Forms.AnchorStyles.Right)));

To dock your picture box (so it fills the entire containing control):

停靠您的图片框(使其填充整个包含控件):

this.PresPB.Dock = System.Windows.Forms.DockStyle.Fill;

You also need to change this line:

您还需要更改此行:

this.Controls.Add(PresPB);

to this:

对此:

PresGB.Controls.Add(PresPB);