【问题标题】:How do you resize a form to fit its content automatically?如何自动调整表单大小以适应其内容?
【发布时间】:2011-05-11 10:12:58
【问题描述】:

我正在尝试实现以下行为:

在表单上有一个选项卡控件。在该选项卡控件上有一个树视图。为了防止出现滚动条,我希望表单在第一次显示时根据树视图的内容更改其大小。

如果树视图有太多节点无法在表单的默认大小上显示,则表单应更改其大小,以便树视图上没有垂直滚动条(达到屏幕大小允许的最大大小)。

我需要知道的是,是否可以通过控件的属性来实现这种行为。我确信这可以通过以编程方式计算和设置元素的大小来实现,但我想知道是否有办法通过 AutoSizeMode 等设置来实现这一点。

[更新]

这是我的应用程序用户看到的第一个对话框:这是一个选择要使用的数据库的对话框。它是一个数据库列表,带有一个 tabcontrol、buttens 等。如果列表太长,滚动条就会出现,我的一个同事希望它们消失。

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    使用 AutoSize 和 AutoSizeMode 属性。

    http://msdn.microsoft.com/en-us/library/system.windows.forms.form.autosize.aspx

    一个例子:

    private void Form1_Load(object sender, EventArgs e)
    {
        // no smaller than design time size
        this.MinimumSize = new System.Drawing.Size(this.Width, this.Height);
    
        // no larger than screen size
        this.MaximumSize = new System.Drawing.Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, (int)System.Windows.SystemParameters.PrimaryScreenHeight);
    
        this.AutoSize = true;
        this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
    
        // rest of your code here...
    }
    

    【讨论】:

    • 我尝试做这样的事情,但我发现这种方法与停靠和锚点相结合有时会产生非常奇怪的行为。所以它本身可能工作正常,但如果你有任何类型的对接,那么它可能不值得麻烦。
    • System.Windows.SystemParameters 已过时,不适用于当前版本的 .NET。考虑修改。
    • 我试过了,但是当中心锚定列表框的内容增加时,我仍然无法让表单增加。相反,我在列表框中得到了一个滚动条。我没有在列表框本身上看到任何自动调整大小的属性。我猜我需要把它放在一个自动调整大小的面板中作为停靠完整?
    • 我想添加项目,调整大小,然后允许用户也调整大小。所以我所做的是AutoSize = true; OnResize(e); 调整大小以适应新控件,然后保存新大小var newSize = new System.Drawing.Size(this.Width, this.Height); 然后关闭自动调整大小以保持用户控制。但是,在这样做时,表单会恢复到以前的大小,因此您可以通过this.Size = newSize 强制它。还有维奥拉!按需自动调整大小并保持用户可调。认为我应该分享。
    【解决方案2】:

    通过使用各种大小调整属性(Dock、Anchor)或容器控件(Panel、TableLayoutPanel、FlowLayoutPanel 等),您只能指定从外部控件到内部控件的大小。但是.Net 框架中没有任何东西(工作)允许通过子控件的大小来规定容器的大小。我也错过了几次,并尝试了 AutoSize 属性,但它从未奏效。

    所以你所能做的就是尝试手动完成这些工作,抱歉。

    【讨论】:

    • 是的,在这个方向上我也一直手动完成。 @jgaufin 的警告确实适用!
    • 实际上,AutoSize 属性确实 工作,只是不是很好,特别是如果您还尝试停靠或锚定任何包含的控件。 WinForms 那时通常只会精神崩溃。您应该将容器自动调整为控件的大小将控件锚定/停靠到容器,但不要同时使用两者。实际上,从头开始......只是避免使用 AutoSize。你的理智会感谢你。
    • 同意,避免使用 autosize 即使它可以工作。不使用它的另一个重要原因是它会阻止用户在运行时手动更改表单的大小。您几乎总是希望用户能够手动控制表单的大小,如果您确实想自动调整表单的大小,它通常伴随着一个事件,所以只需使用一些代码来处理事件来调整大小而不是设置属性自动调整整个表单的行为。
    • 您还可以取消停靠、自动调整大小和重新停靠...dataGridView1.Dock = DockStyle.None; dataGridView1.AutoSize = true; this.AutoSize = true; dataGridView1.Dock = DockStyle.Fill;
    【解决方案3】:

    来自MSDN

    为了最大限度地提高工作效率,Windows 窗体设计器隐藏了 AutoSize 类的 Form 属性。 在设计时,表单 表现得好像 AutoSize 属性设置为 false, 无论其实际设置如何。 运行时,无特殊 进行了调整,并将AutoSize 属性应用为 由属性设置指定。

    【讨论】:

      【解决方案4】:

      这可能很有用。 它将新表单的大小调整为用户控件,然后将用户控件锚定到新表单:

      Form f = new Form();
      MyUserControl muc = new MyUserControl();
      f.ClientSize = muc.Size;
      f.Controls.Add(muc);
      muc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
      f.ShowDialog();
      

      【讨论】:

        【解决方案5】:

        您可以通过计算节点的高度,将其乘以节点数,然后相应地设置表单的 MinimumSize 属性来计算 TreeView 所需的高度。

        // assuming the treeview is populated!
        nodeHeight = treeview1.Nodes[0].Bounds.Height;
        
        this.MaximumSize = new Size(someMaximumWidth, someMaximumHeight);
        
        int requiredFormHeight = (treeView1.GetNodeCount(true) * nodeHeight);
        
        this.MinimumSize = new Size(this.Width, requiredFormHeight);
        

        注意。这假设虽然 treeview1 是表单上的唯一控件。设置 requiredFormHeight 变量时,您需要考虑树视图周围的其他控件和高度要求,例如您提到的 tabcontrol。

        (不过,我同意@jgauffin 并评估在未经用户同意的情况下每次加载表单时调整表单大小的要求背后的基本原理 - 也许让用户定位和调整表单大小并记住这一点??)

        【讨论】:

        • 我必须创建自己的“警报对话框”实现来模仿原始的 .NET 对话框窗口。在我的例子中,我需要创建一个对话框窗口来适应表单内动态生成的标签文本。所以,基本上我只需要测量窗口内的动态控件高度和宽度,并像这个答案一样调整表单的宽度和高度MinimumSize 属性。我将控件的AutoSize 属性和表单本身设置为true。使用其MaximumSize 属性微调控件
        【解决方案6】:

        这项技术解决了我的问题:

        在父表单中:

        frmEmployee frm = new frmEmployee();
        frm.MdiParent = this;
        frm.Dock = DockStyle.Fill;
        frm.Show();
        

        在子窗体中(Load 事件):

        this.WindowState = FormWindowState.Maximized;
        

        【讨论】:

          【解决方案7】:

          如果您尝试根据表格调整内容,则以下内容会有所帮助。当我尝试调整表单上的内容以适应表单大小调整时,它可以帮助我。

          this.contents.Size = new Size(this.ClientRectangle.Width, this.ClientRectangle.Height);

          【讨论】:

            【解决方案8】:

            我在我的项目中使用此代码,对我有用。

                private void Form1_Resize(object sender, EventArgs e)
                {
                    int w = MainPanel.Width; // you can use form.width when you don't use panels
            
                    w = (w - 120)/4; // 120 because set 15px for each side of panels
                                     // and put panels in FlowLayoutPanel
                                     // 4 because i have 4 panel boxes
                    panel1.Width = w;
                    panel2.Width = w;
                    panel3.Width = w;
                    panel4.Width = w;
                }
            

            【讨论】:

              【解决方案9】:

              我使用了这段代码,它工作得很好

              const int margin = 5;
                      Rectangle rect = new Rectangle(
                          Screen.PrimaryScreen.WorkingArea.X + margin,
                          Screen.PrimaryScreen.WorkingArea.Y + margin,
                          Screen.PrimaryScreen.WorkingArea.Width - 2 * margin,
                          Screen.PrimaryScreen.WorkingArea.Height - 2 * (margin - 7));
                      this.Bounds = rect;
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-06-05
                • 1970-01-01
                • 2011-02-26
                • 1970-01-01
                • 1970-01-01
                • 2019-08-27
                • 2021-05-21
                • 1970-01-01
                相关资源
                最近更新 更多