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

本文关键字:控件 垂直 对齐 动态 添加 winforms 水平 | 更新日期: 2023-09-27 18:33:55

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

我现在有这个代码:

    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();
        }
    }

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

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

也许FlowLayoutPanel控件已经执行了您要执行的操作。只需创建您的图片框并将它们添加到FlowLayoutPanel而不是GroupBox

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

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

如果您更喜欢GroupBox的边框,您仍然可以将FlowLayoutPanel放入GroupBox中。

若要调整图片框之间的间距,可以使用 Margin 属性。

这使您可以对布局进行大量控制,并且无需计算控制位置。此外,如果FlowLayoutPanel的大小发生变化,则会自动重新排列所有内容。

更新:

我对你的代码有一些评论:

  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. 你使用"神秘"的名字。 PresGBPresPB很可能被意外交换。缩写通常是名称的糟糕选择。

  5. 无需调用SendToBackBringToFront,因为您不希望控件重叠。

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

将 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(); 

您始终可以在窗体上放置控件,执行要执行的操作,然后查看设计器生成的代码以了解设计器如何执行此操作(在"Designer.cs"文件中(。 在后台,它加载所有控件并通过代码设置所有属性。

话虽如此。

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

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

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)));

要停靠图片框(以便填充整个包含控件(,请执行以下操作:

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

您还需要更改此行:

this.Controls.Add(PresPB);

对此:

PresGB.Controls.Add(PresPB);