繁体   English   中英

winforms c# 中的自动调整项目/控件大小显示错误

[英]Auto resizing items/controls in winforms c# showing error

我一直在尝试使我的 windows 表单应用程序自动调整大小,即当用户调整应用程序的大小时,它的控件也会相应地调整大小,在网上搜索后,我以 a.cs 文件的形式遇到了以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

public class clsResize
{
    List<System.Drawing.Rectangle> _arr_control_storage = new List<System.Drawing.Rectangle>();
    private bool showRowHeader = false;
    public clsResize(Form _form_)
    {
        form = _form_; //the calling form
        _formSize = _form_.ClientSize; //Save initial form size
        _fontsize = _form_.Font.Size; //Font size
    }

    private float _fontsize  { get; set; }

    private System.Drawing.SizeF _formSize {get;set; }

    private Form form { get; set; }

    public void _get_initial_size() //get initial size//
    {
        var _controls = _get_all_controls(form);//call the enumerator
        foreach (Control control in _controls) //Loop through the controls
        {
            _arr_control_storage.Add(control.Bounds); //saves control bounds/dimension            
            //If you have datagridview
            if (control.GetType() == typeof(DataGridView))
                _dgv_Column_Adjust(((DataGridView)control), showRowHeader);
        }
    }

    public void _resize() //Set the resize
    {
        double _form_ratio_width = (double)form.ClientSize.Width /(double)_formSize.Width; //ratio could be greater or less than 1
        double _form_ratio_height = (double)form.ClientSize.Height / (double)_formSize.Height; // this one too
        var _controls = _get_all_controls(form); //reenumerate the control collection
        int _pos = -1;//do not change this value unless you know what you are doing
        foreach (Control control in _controls)
        {
            // do some math calc
            _pos += 1;//increment by 1;
            System.Drawing.Size _controlSize = new System.Drawing.Size((int)(_arr_control_storage[_pos].Width * _form_ratio_width),
                (int)(_arr_control_storage[_pos].Height * _form_ratio_height)); //use for sizing

            System.Drawing.Point _controlposition = new System.Drawing.Point((int)
            (_arr_control_storage[_pos].X * _form_ratio_width),(int) (_arr_control_storage[_pos].Y * _form_ratio_height));//use for location

            //set bounds
            control.Bounds = new System.Drawing.Rectangle(_controlposition, _controlSize); //Put together

            //Assuming you have a datagridview inside a form()
            //if you want to show the row header, replace the false statement of 
            //showRowHeader on top/public declaration to true;
            if (control.GetType() == typeof(DataGridView))
                _dgv_Column_Adjust(((DataGridView)control), showRowHeader);


            //Font AutoSize
            control.Font = new System.Drawing.Font(form.Font.FontFamily,
             (float)(((Convert.ToDouble(_fontsize) * _form_ratio_width) / 2) +
              ((Convert.ToDouble(_fontsize) * _form_ratio_height) / 2)));

        }
    }

    private void _dgv_Column_Adjust(DataGridView dgv, bool _showRowHeader) //if you have Datagridview 
    //and want to resize the column base on its dimension.
    {
        int intRowHeader = 0;
        const int Hscrollbarwidth = 5;
        if (_showRowHeader)
            intRowHeader = dgv.RowHeadersWidth;
        else
            dgv.RowHeadersVisible = false;

        for (int i = 0; i < dgv.ColumnCount; i++)
        {
            if (dgv.Dock == DockStyle.Fill) //in case the datagridview is docked
                dgv.Columns[i].Width = ((dgv.Width - intRowHeader) / dgv.ColumnCount);
            else
                dgv.Columns[i].Width = ((dgv.Width - intRowHeader - Hscrollbarwidth) / dgv.ColumnCount);
        }
    } 


      

    private static IEnumerable<Control> _get_all_controls(Control c)
    {
        return c.Controls.Cast<Control>().SelectMany(item =>
            _get_all_controls(item)).Concat(c.Controls.Cast<Control>()).Where(control => 
            control.Name != string.Empty);
    }
}

我将此添加到我在代码中使用的项目中,如下所示:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace KryptonTest
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : KryptonForm
    {
        clsResize _form_resize;
        
        
        public MainForm()
        {
            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();
            

            _form_resize = new clsResize(this);
            this.Load += MainFormLoad;
            this.Resize += MainFormResize;
        }

        void MainFormLoad(object sender, EventArgs e)
        {

            _form_resize._get_initial_size();
            
        }

        void MainFormResize(object sender, EventArgs e)
        {
            _form_resize._resize();
        }
    }
}

但是当我运行它时,我两次收到以下错误

错误信息

我该如何解决?

你确定枚举工作正常吗? 错误消息告诉您列表中的项目少于您尝试调用的项目。

指数超出范围。 必须是非负数且小于集合的大小。 参数名称:索引

当我们调整表单大小时,我们通常会选择一些控件来变大,而其他控件则不会 - 将名称 TextBox 或 Checkbox 的宽度和高度加倍并没有多大意义,因为您不会键入/看到更多的文本在他们中。 其他项目,如日志列表框、email 正文设计器 TextBox 等,调整这些内容的大小是有意义的。

安排调整大小的布局非常简单:每个控件都有一个 Anchor 属性,当设置特定侧的锚点时,控件将移动或调整大小,因此控件和容器的给定边缘之间的距离相同。 显然,如果一个控件锚定在相对的两侧,那么当它所在的容器变大时它会伸展

一些例子:

  • 文本框宽 100,高 20,锚定在左上角。 表格宽 200 像素,高 200 像素。 TextBox 似乎没有移动或增长; 它与左上角的距离保持不变

  • TextBox 是 100 宽和 20 高,锚定在右上角。 表格宽 200 像素,高 200 像素。 TextBox 向右移动 200 个像素,因为它是右锚定的,并且在窗体右边缘之间保持相同的距离。 它不会变宽; 它与左上角的距离保持不变。 它不会长得更高,因为它是顶部锚定而不是底部锚定

  • TextBox 是 100 宽和 20 高,锚定在左上角右下角。 它是一个多行文本框。 表格宽 200 像素,高 200 像素。 由于表单增长了 200x200,因此 TextBox 变宽了 200 像素,变高了 200 像素 - 四周的锚点意味着文本框边缘与表单边缘的距离相同

  • 您需要连续 3 个文本框,当表单变宽时,中间的文本框应该变宽; 其他两个文本框不应该增长

    • 您将左侧的 TextBox 锚定在左上角
    • 您将中间的文本框锚定在左上角
    • 您将正确的 TextBox 锚定在右上角
  • 当表单变宽时,左边的 TextBox 保持不动,右边的 TextBox 向右移动,随着表单变宽,中间的 TextBox 横向扩展,与表单变宽一样多

当双方都没有锚定时,控件在该方向移动调整大小距离的一半

不要忘记您可以将面板放入以一种方式锚定的面板,然后在其中以另一种方式锚定的控件。 对于其他类型的布局,您可能需要一个表格或流布局面板,但对于大多数 UI,锚定系统工作得很好

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM