精华内容
下载资源
问答
  • C# WinForm窗口自适应布局

    千次阅读 2019-06-22 15:31:37
    本文用一个实际布局案例,介绍了利用`Docker`和`Anchor`来实现一个自适应大小的界面布局,以及控件放置顺序对布局效果的影响。

    【转载请注明出处:https://blog.csdn.net/Leytton/article/details/92447713】

    如果本文对您有所帮助,请点个赞让我知道哦 😃
    本文用一个实际布局案例,介绍了利用DockerAnchor来实现一个自适应大小的界面布局,以及控件放置顺序对布局效果的影响。
    我们从一张图开始说起,如下图所示,窗体调整大小时,C处列表组件会自动缩放填充满。

    在这里插入图片描述
    这是缩小后的界面:
    在这里插入图片描述
    布局属性:
    A MenuStrip 菜单控件,Docker属性为Top
    B Panel 面板控件,Docker属性为Top
    C ListVIew 列表控件,Docker属性为Fill
    D StatusStrip 状态控件,Docker属性为Bottom

    其他:
    全选按钮:Docker属性为NoneAnchor属性为Top, Left
    开启按钮:Docker属性为NoneAnchor属性为Top, Right
    停止按钮:Docker属性为NoneAnchor属性为Top, Right

    说明下:
    1、Docker属性为None时,Anchor属性才有效
    2、Anchor可以理解为停靠依附,就像用钉子定住了一样,属性为Top, Right则无论怎样调整窗口大小,控件与父控件上方、右方的距离永远不变,其它属性类似。
    3、DockerFill属性则会填满父控件,为Top时就会从父控件的顶部开始填充一定高度,但是,会按底层控件先填充的原则,所以控件放置的先后顺序会对填充效果造成影响。
    比如:
    如下图所示,把 B控件(Docker属性为Top)置于底层,则B控件的位置移到了最上面:
    在这里插入图片描述
    如下图所示,把C控件(Docker属性为Fill)置于底层,则C控件的顶部被其他控件遮挡:
    在这里插入图片描述

    展开全文
  • 之前写过winform的窗体自适应,不过原生控件没有圆角,最近在使用Dskin开发,所以就写了可以让窗体和控件大小,位置,字体,圆角一起自适应的方案。 调用时 在需要自适应的窗体的构造方法中, InitializeComponent...
  • 本来不爱鸡汤,今天说两句:winform开发有一个缺陷就是不能实现界面自适应,切换不同的分辨率,或者窗体大小改变就会出现窗体显示不全的问题。这就需要自己写一个方法来实现不同情况下的自适应,WPF比Winform的一...

    今天给大家上一道硬菜。本来不爱鸡汤,今天说两句:winform开发有一个缺陷就是不能实现界面的自适应,切换不同的分辨率,或者窗体大小改变就会出现窗体显示不全的问题。这就需要自己写一个方法来实现不同情况下的自适应,WPF比Winform的一个显著优势就是可以实现自适应。今天给大家一个可以实现自适应的方案。(本篇博客代码,为本人,在本地调试通过后,手敲到博客中,难免出现敲错的状况,勿喷。代码里面的注释是比较清楚的)

    效果图:

     

    调整大小后

    新建一个AutoSizeFormClass.cs文件

    class AutoSizeFormClass
    {
        //1.声明一个结构体,记录窗体和控件的基本属性
        public struct controlRect
        {
            public string Name;
            public int Left;
            public int Top;
            public int Width;
            public int Height;
            public float FontSize;
            public FontFamily FontFamily;
        }
        //2.声明一个集合记录所有控件的属性
        //使用控件的Name作为key
        Dictionary<string,controlRect> dic=new Dictionary<string,controlRect>();
        int ctrNo=0;
        //这里是你开发环境下的分辨率
        private int ScW=1920;
        private int ScH=1080;
        //记录窗体是不是第一次加载的标记 0:第一次加载  1:重复加载
        private int IsFirstLoad=0;
        //窗体的名称
        private string FrmName=string.Empty;
        //3.创建两个函数
        //采用递归的方法将控件包含的所有控件属性记录下来(结构体的每一个属性都需要赋值)
        private void AddControl(Control ctl)
        {
            foreach(Control c in ctl.Controls)
            {
                GetCtrParameter(c);
                //使用递归函数先记录控件本身,后记录控件包含的子控件
                if(c.Controls.Count>0)
                {
                    AddControl(c);
                }
            }
        }
        //获取控件的所有属性
        private void GetCtrParameter(Control mForm)
        {
            controlRect cr;
            cr.Name=mForm.Name;
            cr.Left=mForm.Left;
            cr.Top=mForm.Top;
            cr.Width=mForm.Width;
            cr.Height=mForm.Height;
            cr.FontSize=mForm.Font.Size;
            cr.FontFamily=mForm.Font.FontFamily;
            dic.Add(cr.Name,cr);
        }
    
        //4.控件自适应大小
        public void controlAutoSize(Control mForm)
        {
            FrmName=mForm.Name;
            float wScale=0;
            float hScale=0;
            //因为有些控件和DataGridView的子空间加载时间较长,所以在Form1_SizeChanged中,
            //记录控件的原始大小和位置,第一次加载的时候先根据和开发环境的像素比例绘制窗体                
            if(IsFirstLoad==0&&ctrNo==0)
            {
                //获取当前的像素
                int SH=Screen.PrimaryScreen.Bounds.Height;
                int SW=Screen.PrimaryScreen.Bounds.Width;
                //和开发环境的像素相比获取对应的比值
                wScale=(float)SH/(float)ScH;
                hScale=(float)SW/(float)ScW;
                controlRect cR;
                cR.Name=mForm.Name;
                cR.Left=mForm.Left;
                cR.Top=mForm.Top;
                cR.Width=mForm.Width;
                cR.Height=mForm.Height;
                cR.FontSize=mForm.Font.Size;
                cR.FontFamily=mForm.Font.FontFamily;
                dic.Add(cR.Name,cR);//第一个为窗体本身
                AddControl(mForm);//递归获取所有窗体基础信息
                AutoScaleControl(mForm,wScale,hScale);//这里其实是第一次构造窗体
                IsFirstLoad=1;            
            }
            //这里是改变窗体大小时重新设置窗体的属性
            else
            {
                //新旧窗体之间的高和长的比例,与第一次加载的信息比较
                wScale=(float)mForm.Width/dic[FrmName].Width;
                hScale=(float)mForm.Height/dic[FrmName].Height;
                //将ctrNo设为1,代表为控件而非窗体
                ctrNo=1;
                //设置控件以及其嵌套的控件的比例大小,使用递归调用
                AutoScaleControl(mForm,wScale,hScale);
            }
        }
        //递归进行自适应调整
        private void AutoScaleControl(Control ctl,float wScale,float hScale)
        {
            int ctrLeft0,ctrTop0,ctrWidth0,ctrHeight0;
            float fontSize;
            FontFamily fontFamily;
            foreach(Control c in ctl.Controls)
            {
                string ctrName=c.Name;
                ctrLeft0=dic[ctrName].Left;
                ctrTop0=dic[ctrName].Top;
                ctrWidth0=dic[ctrName].Width;
                ctrHeight0=dic[ctrName].Height;
                fontSize=dic[ctrName].FontSize;
                fontFamily=dic[ctrName].FontFamily;
                //新旧控件之间的线性比例,字体大小依据高度转换
                c.Left=(int)(ctrLeft0*wScale);
                c.Top=(int)(ctrTop0*hScale);
                c.Width=(int)(ctrWidth0*wScale);
                c.Height=(int)(ctrHeight0*hScale);
                c.Font=new Font(fontFamily,fontSize*hScale);
                ctrNo++;
                //先缩放控件本身,后缩放控件的子控件
                if(c.Controls.Count>0)
                {
                    AutoScaleControl(c,wScale,hScale);
                }
                //dataGridview特殊处理
                if(c is DataGridView)
                {
                    DataGridView dgv=c as DataGridView;
                    Cursor.Current=Cursors.WaitCursor;
                    int widths=0;
                    for(int i=0;i<dgv.Columns.Count-1;i++)
                    {
                        //自动调整列宽
                        dgv.AutoResizeColumn(i,DataGridViewAutoSizeColumnMode.AllCells);
                        widths+=dgv.Columns[i].Width;
                    }
                    //如果调整列的宽度大于设定宽度
                    if(widths>ctl.Size.Width)
                    {
                                    dgv.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.DisplayedCells;//调整列的模式
    
                    }
                    else
                    {
                        dgv.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.Fill;//如果小于则填充
                       
                    }
                     Cursor.Current=Cursors.Default;
                }
            }
        }
    
    }
    

    添加一个Form1,在SizeChanged方法添加,不要在load中添加

    public partial class Form1:Form
    {
        private AutoSizeFormClass asc=new AutoSizeFormClass();
        public Form1()
        {
            InitializeComponent();
        } 
        private void Form1_SizeChanged(object sender,EventArgs e)
        {
            asc.controlAutoSize(this);
        }
    }

     

     

     

    展开全文
  • WinForm窗体自适应

    2016-12-05 22:43:00
    首先贴出 Rocky 博客上的自适应代码: AutoSizeFormClass.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System....

    首先贴出 Rocky 博客上的自适应代码:

    AutoSizeFormClass.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WinAuto
    {
        public class AutoSizeFormClass
        {
            //(1).声明结构,只记录窗体和其控件的初始位置和大小。
            public struct controlRect
            {
                public int Left;
                public int Top;
                public int Width;
                public int Height;
            }
            //(2).声明 1个对象
            //注意这里不能使用控件列表记录 List nCtrl;,因为控件的关联性,记录的始终是当前的大小。
            //      public List oldCtrl= new List();//这里将西文的大于小于号都过滤掉了,只能改为中文的,使用中要改回西文
            public List<controlRect> oldCtrl = new List<controlRect>();
            int ctrlNo = 0;//1;第0个为窗体本身,窗体内的控件,从序号1开始
            //(3). 创建两个函数
            //(3.1)记录窗体和其控件的初始位置和大小,
            public void controllInitializeSize(Control mForm)
            {
                controlRect cR;
                cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
                oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可
                AddControl(mForm);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
                //this.WindowState = (System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化
                //0 - Normalize , 1 - Minimize,2- Maximize
                controlAutoSize(mForm);
            }
            private void AddControl(Control ctl)
            {
                foreach (Control c in ctl.Controls)
                {
                    controlRect objCtrl;
                    objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height;
                    oldCtrl.Add(objCtrl);
                    //**放在这里,是先记录控件本身,后记录控件的子控件
                    if (c.Controls.Count > 0)
                        AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
                }
            }
            //(3.2)控件自适应大小,
            public void controlAutoSize(Control mForm)
            {
                if (ctrlNo == 0)
                { //*如果在窗体的Form1_Load中,记录控件原始的大小和位置,正常没有问题,但要加入皮肤就会出现问题,因为有些控件如dataGridView的的子控件还没有完成,个数少
                    //*要在窗体的Form1_SizeChanged中,第一次改变大小时,记录控件原始的大小和位置,这里所有控件的子控件都已经形成
                    controlRect cR;
                    //  cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
                    cR.Left = 0; cR.Top = 0; cR.Width = mForm.PreferredSize.Width; cR.Height = mForm.PreferredSize.Height;
    
                    oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可
                    AddControl(mForm);//窗体内其余控件可能嵌套其它控件(比如panel),故单独抽出以便递归调用
                }
                float wScale = (float)mForm.Width / (float)oldCtrl[0].Width;//新旧窗体之间的比例,与最早的旧窗体
                float hScale = (float)mForm.Height / (float)oldCtrl[0].Height;//.Height;
                ctrlNo = 1;//进入=1,第0个为窗体本身,窗体内的控件,从序号1开始
                AutoScaleControl(mForm, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
            }
            private void AutoScaleControl(Control ctl, float wScale, float hScale)
            {
                int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0;
                //int ctrlNo = 1;//第1个是窗体自身的 Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始
                foreach (Control c in ctl.Controls)
                { //**放在这里,是先缩放控件的子控件,后缩放控件本身
                    //if (c.Controls.Count > 0)
                    //   AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
                    ctrLeft0 = oldCtrl[ctrlNo].Left;
                    ctrTop0 = oldCtrl[ctrlNo].Top;
                    ctrWidth0 = oldCtrl[ctrlNo].Width;
                    ctrHeight0 = oldCtrl[ctrlNo].Height;
                    //c.Left = (int)((ctrLeft0 - wLeft0) * wScale) + wLeft1;//新旧控件之间的线性比例
                    //c.Top = (int)((ctrTop0 - wTop0) * h) + wTop1;
                    c.Left = (int)((ctrLeft0) * wScale);//新旧控件之间的线性比例。控件位置只相对于窗体,所以不能加 + wLeft1
                    c.Top = (int)((ctrTop0) * hScale);//
                    c.Width = (int)(ctrWidth0 * wScale);//只与最初的大小相关,所以不能与现在的宽度相乘 (int)(c.Width * w);
                    c.Height = (int)(ctrHeight0 * hScale);//
                    ctrlNo++;//累加序号
                    //**放在这里,是先缩放控件本身,后缩放控件的子控件
                    if (c.Controls.Count > 0)
                        AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
    
                    if (ctl is DataGridView)
                    {
                        DataGridView dgv = ctl as DataGridView;
                        Cursor.Current = Cursors.WaitCursor;
    
                        int widths = 0;
                        for (int i = 0; i < dgv.Columns.Count; i++)
                        {
                            dgv.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells);  // 自动调整列宽  
                            widths += dgv.Columns[i].Width;   // 计算调整列后单元列的宽度和                       
                        }
                        if (widths >= ctl.Size.Width)  // 如果调整列的宽度大于设定列宽  
                            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;  // 调整列的模式 自动  
                        else
                            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;  // 如果小于 则填充  
    
                        Cursor.Current = Cursors.Default;
                    }
                }
    
    
            }
        }
    }

    Form1.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WinAuto
    {
        public partial class Form1 : Form
        {
            //自动计算控件大小
            public AutoSizeFormClass asc = new AutoSizeFormClass();
            public List<User> lu = new List<User>();
            public User a = new User() { Name = "Vampire", Age = 1000, Sex = "M", Tel = "177478657376" };
            int change = 5;
    
            public Form1()
            {
                InitializeComponent();
    
                //asc.controllInitializeSize(this);
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                lu = new List<User>();
                for (int i = 0; i < 10; i++)
                {
                    lu.Add(a);
                }
                dataGridView1.DataSource = lu;
                //this.MaximumSize = new Size(600, 500);  //限制窗体的最大宽度为600,最大高度为500
                //this.MinimumSize = new Size(500, 400);  //限制窗体的最小宽度为370,最小高度为240
                //dataGridView1_mycolor(sender, e);
                //tabControl1.SelectedIndex = 1;
                //tabControl1.SelectedIndex = 0;
                asc.controllInitializeSize(this);
                //asc.controlAutoSize(this);
            }
    
            private void Form1_SizeChanged(object sender, EventArgs e)
            {
                asc.controlAutoSize(this);
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                lu = new List<User>();
                for (int i = 0; i < change*10; i++)
                {
                    lu.Add(a);
                }
                change++;
                dataGridView1.DataSource = lu;
                //Form1_SizeChanged(sender, e);
            }
    
            private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
            {
                //自动编号,与数据无关
                Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, dataGridView1.RowHeadersWidth - 4, e.RowBounds.Height);
                TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), dataGridView1.RowHeadersDefaultCellStyle.Font, rectangle, dataGridView1.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
            }
    
            private void dataGridView1_mycolor(object sender, EventArgs e)
            {
                if (this.dataGridView1.Rows.Count != 0)
                {
                    for (int i = 0; i < dataGridView1.RowCount; i += 2)
                    {
                        this.dataGridView1.Rows[i].DefaultCellStyle.BackColor = System.Drawing.Color.GreenYellow;
                    }
                }
            }
    
            private void dataGridView1_DataSourceChanged(object sender, EventArgs e)
            {
                if (this.dataGridView1.Rows.Count != 0)
                {
                    for (int i = 0; i < dataGridView1.RowCount; i += 2)
                    {
                        this.dataGridView1.Rows[i].DefaultCellStyle.BackColor = System.Drawing.Color.GreenYellow;
                    }
                }
            }
    
            //定义最小界面尺寸,防止按钮被挤掉
            private void Form1_ResizeEnd(object sender, EventArgs e)
            {
                //if (this.Width <= 500)
                //{
                //    this.Width = 500;
                //}
                //if (this.Height <= 350)
                //{
                //    this.Height = 350;
                //}
            }
    
            private void tabControl1_TabIndexChanged(object sender, EventArgs e)
            {
                asc.controlAutoSize(this);
            }
    
            private void Form1_Shown(object sender, EventArgs e)
            {
                //asc.controllInitializeSize(this);
            }
    
            private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
            {
                asc.controlAutoSize(this);
            }
    
    
    
        }
    }

    Form1.Designer.cs

    namespace WinAuto
    {
        partial class Form1
        {
            /// <summary>
            /// 必需的设计器变量。
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// 清理所有正在使用的资源。
            /// </summary>
            /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows 窗体设计器生成的代码
    
            /// <summary>
            /// 设计器支持所需的方法 - 不要
            /// 使用代码编辑器修改此方法的内容。
            /// </summary>
            private void InitializeComponent()
            {
                this.components = new System.ComponentModel.Container();
                this.dataGridView1 = new System.Windows.Forms.DataGridView();
                this.button1 = new System.Windows.Forms.Button();
                this.statusStrip1 = new System.Windows.Forms.StatusStrip();
                this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
                this.tabControl1 = new System.Windows.Forms.TabControl();
                this.tabPage1 = new System.Windows.Forms.TabPage();
                this.tabPage2 = new System.Windows.Forms.TabPage();
                this.dataGridView2 = new System.Windows.Forms.DataGridView();
                this.nameDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.ageDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.telDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.sexDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.userBindingSource = new System.Windows.Forms.BindingSource(this.components);
                this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
                this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn();
                ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
                this.statusStrip1.SuspendLayout();
                this.tabControl1.SuspendLayout();
                this.tabPage1.SuspendLayout();
                this.tabPage2.SuspendLayout();
                ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit();
                ((System.ComponentModel.ISupportInitialize)(this.userBindingSource)).BeginInit();
                this.SuspendLayout();
                // 
                // dataGridView1
                // 
                this.dataGridView1.AutoGenerateColumns = false;
                this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
                this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
                this.nameDataGridViewTextBoxColumn,
                this.ageDataGridViewTextBoxColumn,
                this.telDataGridViewTextBoxColumn,
                this.sexDataGridViewTextBoxColumn});
                this.dataGridView1.DataSource = this.userBindingSource;
                this.dataGridView1.Location = new System.Drawing.Point(15, 25);
                this.dataGridView1.Name = "dataGridView1";
                this.dataGridView1.RowTemplate.Height = 23;
                this.dataGridView1.Size = new System.Drawing.Size(616, 286);
                this.dataGridView1.TabIndex = 0;
                this.dataGridView1.DataSourceChanged += new System.EventHandler(this.dataGridView1_DataSourceChanged);
                this.dataGridView1.RowPostPaint += new System.Windows.Forms.DataGridViewRowPostPaintEventHandler(this.dataGridView1_RowPostPaint);
                // 
                // button1
                // 
                this.button1.Location = new System.Drawing.Point(294, 12);
                this.button1.Name = "button1";
                this.button1.Size = new System.Drawing.Size(75, 23);
                this.button1.TabIndex = 1;
                this.button1.Text = "刷新";
                this.button1.UseVisualStyleBackColor = true;
                this.button1.Click += new System.EventHandler(this.button1_Click);
                // 
                // statusStrip1
                // 
                this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.toolStripStatusLabel1});
                this.statusStrip1.Location = new System.Drawing.Point(0, 424);
                this.statusStrip1.Name = "statusStrip1";
                this.statusStrip1.Size = new System.Drawing.Size(680, 22);
                this.statusStrip1.TabIndex = 2;
                this.statusStrip1.Text = "statusStrip1";
                // 
                // toolStripStatusLabel1
                // 
                this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
                this.toolStripStatusLabel1.Size = new System.Drawing.Size(78, 17);
                this.toolStripStatusLabel1.Text = "aaaaaaaaaa";
                // 
                // tabControl1
                // 
                this.tabControl1.Controls.Add(this.tabPage1);
                this.tabControl1.Controls.Add(this.tabPage2);
                this.tabControl1.Location = new System.Drawing.Point(12, 41);
                this.tabControl1.Name = "tabControl1";
                this.tabControl1.SelectedIndex = 0;
                this.tabControl1.Size = new System.Drawing.Size(655, 366);
                this.tabControl1.TabIndex = 3;
                this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged);
                this.tabControl1.TabIndexChanged += new System.EventHandler(this.tabControl1_TabIndexChanged);
                // 
                // tabPage1
                // 
                this.tabPage1.Controls.Add(this.dataGridView1);
                this.tabPage1.Location = new System.Drawing.Point(4, 22);
                this.tabPage1.Name = "tabPage1";
                this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
                this.tabPage1.Size = new System.Drawing.Size(647, 340);
                this.tabPage1.TabIndex = 0;
                this.tabPage1.Text = "tabPage1";
                this.tabPage1.UseVisualStyleBackColor = true;
                // 
                // tabPage2
                // 
                this.tabPage2.Controls.Add(this.dataGridView2);
                this.tabPage2.Location = new System.Drawing.Point(4, 22);
                this.tabPage2.Name = "tabPage2";
                this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
                this.tabPage2.Size = new System.Drawing.Size(647, 340);
                this.tabPage2.TabIndex = 1;
                this.tabPage2.Text = "tabPage2";
                this.tabPage2.UseVisualStyleBackColor = true;
                // 
                // dataGridView2
                // 
                this.dataGridView2.AutoGenerateColumns = false;
                this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
                this.dataGridView2.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
                this.dataGridViewTextBoxColumn1,
                this.dataGridViewTextBoxColumn2,
                this.dataGridViewTextBoxColumn3,
                this.dataGridViewTextBoxColumn4});
                this.dataGridView2.DataSource = this.userBindingSource;
                this.dataGridView2.Location = new System.Drawing.Point(15, 27);
                this.dataGridView2.Name = "dataGridView2";
                this.dataGridView2.RowTemplate.Height = 23;
                this.dataGridView2.Size = new System.Drawing.Size(616, 286);
                this.dataGridView2.TabIndex = 1;
                // 
                // nameDataGridViewTextBoxColumn
                // 
                this.nameDataGridViewTextBoxColumn.DataPropertyName = "Name";
                this.nameDataGridViewTextBoxColumn.HeaderText = "姓名";
                this.nameDataGridViewTextBoxColumn.Name = "nameDataGridViewTextBoxColumn";
                this.nameDataGridViewTextBoxColumn.Width = 200;
                // 
                // ageDataGridViewTextBoxColumn
                // 
                this.ageDataGridViewTextBoxColumn.DataPropertyName = "Age";
                this.ageDataGridViewTextBoxColumn.HeaderText = "年龄";
                this.ageDataGridViewTextBoxColumn.Name = "ageDataGridViewTextBoxColumn";
                this.ageDataGridViewTextBoxColumn.Width = 200;
                // 
                // telDataGridViewTextBoxColumn
                // 
                this.telDataGridViewTextBoxColumn.DataPropertyName = "Tel";
                this.telDataGridViewTextBoxColumn.HeaderText = "电话";
                this.telDataGridViewTextBoxColumn.Name = "telDataGridViewTextBoxColumn";
                this.telDataGridViewTextBoxColumn.Width = 200;
                // 
                // sexDataGridViewTextBoxColumn
                // 
                this.sexDataGridViewTextBoxColumn.DataPropertyName = "Sex";
                this.sexDataGridViewTextBoxColumn.HeaderText = "性别";
                this.sexDataGridViewTextBoxColumn.Name = "sexDataGridViewTextBoxColumn";
                this.sexDataGridViewTextBoxColumn.Width = 200;
                // 
                // userBindingSource
                // 
                this.userBindingSource.DataSource = typeof(WinAuto.User);
                // 
                // dataGridViewTextBoxColumn1
                // 
                this.dataGridViewTextBoxColumn1.DataPropertyName = "Name";
                this.dataGridViewTextBoxColumn1.HeaderText = "姓名";
                this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";
                this.dataGridViewTextBoxColumn1.Width = 200;
                // 
                // dataGridViewTextBoxColumn2
                // 
                this.dataGridViewTextBoxColumn2.DataPropertyName = "Age";
                this.dataGridViewTextBoxColumn2.HeaderText = "年龄";
                this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2";
                this.dataGridViewTextBoxColumn2.Width = 200;
                // 
                // dataGridViewTextBoxColumn3
                // 
                this.dataGridViewTextBoxColumn3.DataPropertyName = "Tel";
                this.dataGridViewTextBoxColumn3.HeaderText = "电话";
                this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3";
                this.dataGridViewTextBoxColumn3.Width = 200;
                // 
                // dataGridViewTextBoxColumn4
                // 
                this.dataGridViewTextBoxColumn4.DataPropertyName = "Sex";
                this.dataGridViewTextBoxColumn4.HeaderText = "性别";
                this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4";
                this.dataGridViewTextBoxColumn4.Width = 200;
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(680, 446);
                this.Controls.Add(this.tabControl1);
                this.Controls.Add(this.statusStrip1);
                this.Controls.Add(this.button1);
                this.MinimumSize = new System.Drawing.Size(500, 400);
                this.Name = "Form1";
                this.Text = "Form1";
                this.Load += new System.EventHandler(this.Form1_Load);
                this.Shown += new System.EventHandler(this.Form1_Shown);
                this.ResizeEnd += new System.EventHandler(this.Form1_ResizeEnd);
                this.SizeChanged += new System.EventHandler(this.Form1_SizeChanged);
                ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
                this.statusStrip1.ResumeLayout(false);
                this.statusStrip1.PerformLayout();
                this.tabControl1.ResumeLayout(false);
                this.tabPage1.ResumeLayout(false);
                this.tabPage2.ResumeLayout(false);
                ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit();
                ((System.ComponentModel.ISupportInitialize)(this.userBindingSource)).EndInit();
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
    
            #endregion
    
            private System.Windows.Forms.DataGridView dataGridView1;
            private System.Windows.Forms.BindingSource userBindingSource;
            private System.Windows.Forms.Button button1;
            private System.Windows.Forms.DataGridViewTextBoxColumn nameDataGridViewTextBoxColumn;
            private System.Windows.Forms.DataGridViewTextBoxColumn ageDataGridViewTextBoxColumn;
            private System.Windows.Forms.DataGridViewTextBoxColumn telDataGridViewTextBoxColumn;
            private System.Windows.Forms.DataGridViewTextBoxColumn sexDataGridViewTextBoxColumn;
            private System.Windows.Forms.StatusStrip statusStrip1;
            private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
            private System.Windows.Forms.TabControl tabControl1;
            private System.Windows.Forms.TabPage tabPage1;
            private System.Windows.Forms.TabPage tabPage2;
            private System.Windows.Forms.DataGridView dataGridView2;
            private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
            private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2;
            private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3;
            private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4;
        }
    }
    

     

    User.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WinAuto
    {
        public class User
        {
            string name;
    
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            int age;
    
            public int Age
            {
                get { return age; }
                set { age = value; }
            }
            string tel;
    
            public string Tel
            {
                get { return tel; }
                set { tel = value; }
            }
            string sex;
    
            public string Sex
            {
                get { return sex; }
                set { sex = value; }
            }
        }
    }

     

    转载于:https://my.oschina.net/webcreazy/blog/800396

    展开全文
  • WinForm窗体自适应分辨率

    万次阅读 多人点赞 2014-02-18 21:57:00
    我们自己编写程序的界面,会遇到各种屏幕分辨率,只有自适应才能显的美观。实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比例变化即可。...
        我们自己编写程序的界面,会遇到各种屏幕分辨率,只有自适应才能显的美观。实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比例变化即可。因为窗体上控件的位置和大小是相对于自己所在的窗体的,也就是所谓的窗口坐标。  
      在这里我们只考虑相对于自己窗体的窗口坐标更简单,也就是成比例变化。为了多个窗体共用,我在这里创建一个类AutoSizeFormClass ,1.使用它去记录窗体和其控件的初始位置和大小,2.判断窗体中的控件是否为容器控件,如果是记录容器控件中的控件的初始位置和大小3.根据窗体变化了的大小,成比例地实现其控件的水平和垂直方向的变化,也就是自适应。
     
    二。使用方法
      使用方法很简单,
      1.把自适应的类整体复制到你的工程命名空间里,
         然后在需要自适应的窗体中做2步即可:
      2.声明自适应类实例。
      .为窗体添加大小改变事件,并在其方法中,调用类的自适应方法,完成自适应

        通过上面的介绍我们会发现其中的几个实现难点:
        1.如何保存窗体的以及其中控件的位置以及大小等属性,当然我们最常用的方法就是自己定义一个实体,实体中包含我们需要保持的属性(主要包括left,top,width,height,以及fontsize属性)这个我提供的解决方案是定义一个数据结构。
        普及一下结构体的知识:结构体中包含其中要存储的数据,使用结构体的好处在于可以将不同类型的数据有序的组合在一起,结构造出一个新的数据类型,不占内存空间,只用定义结构体的变量时才开辟内存空间,结构体类型的变量在内存依照其成员顺序顺序排列,所占内存空间的大小是其全体成员所占空间的总和,结构体可以作为函数的参数,函数也可以返回结构体。
    看我们定义的结构体:
     /// <summary>
            /// 声明一个结构,用于保存控件位置的基本属性。
            /// </summary>
            public struct controlRect
            {
                /// <summary>
                /// 控件的left属性
                /// </summary>
                public int Left;
                /// <summary>
                /// 控件的Right属性
                /// </summary>
                public int Top;
                /// <summary>
                /// 控件的Weight属性
                /// </summary>
                public int Width;
                /// <summary>
                /// 控件的High属性
                /// </summary>
                public int Height;
                /// <summary>
                /// 控件的Fontsize属性
                /// </summary>
                public float FontSize;
            }
        然后声明一个泛型用来保存所有控件位置以及大小信息产生的结构体信息。
            /// <summary>
            /// 声明一个泛型,类型为什么的保存控件属性的结构类,
            /// </summary>
            public List<controlRect> oldCtrl = new List<controlRect>();

        

             问题2,如何判断一个控件是否为容器控件,因为我们知道容器控件包含的种类有很多,如panel、groupbox、tabControl等控件,这些也只是我们最常用的,原来我使用的方法是逐个的判读,如下

        //这里只是列出两个容器控件分别为panel控件和groupbox控件
                    if (c.GetType().ToString() == "System.Windows.Forms.Panel")
                    {
                        //要执行的代码
                    }
                    //如果是GroupBox控件
                    if (c.GetType().ToString() == "System.Windows.Forms.GroupBox")
                    {
                        //要执行的代码
                    }

        但我发现自己很难把所有的控件都想全了,即使是想全了也会重复太多的代码,最后采取了一个很有效的方法就是加上这个判断:

                if (c.Controls.Count > 0)

        一旦这个判断成立就说明这个控件就是一个容器控件了。

    问题3.递归调用保存控件信息类,实现所有控件(包括容器控件)的位置和大小信息的保存。

     

     

       问题4.如何保存画窗体时窗体的大小,听起来有些别嘴,其实也可以说是你想要窗体呈现的大小,这个大大家好像会有疑问但虽然说窗体是控件的一种,但是进过我的实现,当我们改变分辨率的同时,比如我们原来设置窗体每次打开时最大化显示,但是无论我们编写程序时设置的窗体的大小多大,我们运行起来时窗体都会占满整个屏幕,这也是出现由于分辨率改变,大窗体中部分控件无法显示完全的原因。比如我们的做的这个很大的登陆界面,看看效果:

            小分辨率下的情况:


           大分辨率下应该是这样:


            ​我们会发现窗体最大化了。但是窗体中的控件没有跟上。
            说了这么多我想大家都迫不及待的想看代码了:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;
    namespace AutoSizeFormClass
    {
        public class AutoSizeFormClass
        {
            /// <summary>
            /// 声明一个结构,用于保存控件位置的基本属性。
            /// </summary>
            public struct controlRect
            {
                /// <summary>
                /// 控件的left属性
                /// </summary>
                public int Left;
                /// <summary>
                /// 控件的Right属性
                /// </summary>
                public int Top;
                /// <summary>
                /// 控件的Weight属性
                /// </summary>
                public int Width;
                /// <summary>
                /// 控件的High属性
                /// </summary>
                public int Height;
                /// <summary>
                /// 控件的Fontsize属性
                /// </summary>
                public float FontSize;
            }
            /// <summary>
            /// 声明一个泛型,类型为什么的保存控件属性的结构类,
            /// </summary>
            public List<controlRect> oldCtrl = new List<controlRect>();
            int ctrlNo = 0;//初始化标识控件的变量为0,表示窗体本身。   
            /// <summary>
            /// 保存控件的位置和大小信息
            /// </summary>
            /// <param name="ctl">需要被保存的控件</param>
            private void AddControl(Control ctl)
            {
                foreach (Control c in ctl.Controls)
                {  
                    controlRect objCtrl;
                    objCtrl.Left = c.Left;
                    objCtrl.Top = c.Top;
                    objCtrl.Width = c.Width;
                    objCtrl.Height = c.Height;
                    objCtrl.FontSize = c.Font.Size;
                    oldCtrl.Add(objCtrl);
                    //**放在这里,是先记录控件本身,后记录控件的子控件,重点是前后要一致
                    if (c.Controls.Count > 0)
                        AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
                }
            }
            /// <summary>
            /// 窗体自适应分辨率类
            /// </summary>
            /// <param name="mForm">需要进行设置的窗体</param>
            public void controlAutoSize(Control mForm)
            {
                if (ctrlNo == 0)
                { //*如果在窗体的Form1_Load中,记录控件原始的大小和位置,正常没有问题,但要加入皮肤就会出现问题,因为有些控件如dataGridView的的子控件还没有完成,个数少
                    //*要在窗体的Form1_SizeChanged中,第一次改变大小时,记录控件原始的大小和位置,这里所有控件的子控件都已经形成
                    controlRect cR;
                    cR.Left = mForm.Left;
                    cR.Top = mForm.Top;
                    cR.Width = mForm.Width;
                    cR.Height = mForm.Height;
                    cR.Width = int.Parse(mForm.Tag.ToString().Split(',')[0]);
                    cR.Height = int.Parse(mForm.Tag.ToString().Split(',')[1]);
                    cR.FontSize = mForm.Font.Size;
                    oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可                
                    AddControl(mForm);//窗体内其余控件可能嵌套其它控件(比如panel),故单独抽出以便递归调用
                }
                float wScale = (float)mForm.Width / (float)oldCtrl[0].Width;//新旧窗体之间的比例,与最早的旧窗体比较
                float hScale = (float)mForm.Height / (float)oldCtrl[0].Height;//.Height;
                ctrlNo = 1;//进入=1,第0个为窗体本身,窗体内的控件,从序号1开始
                AutoScaleControl(mForm, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
            }
            /// 设置控件的属性
            /// </summary>
            /// <param name="ctl">需要设置的控件</param>
            /// <param name="wScale">调整的高度比例</param>
            /// <param name="hScale">调整的宽度比例</param>
            private void AutoScaleControl(Control ctl, float wScale, float hScale)
            {
                int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0;
                float ctrFontSize0;
               //第1个是窗体自身的 Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始
                foreach (Control c in ctl.Controls)
                { 
                    //获得控件原有的位置和大小信息
                    ctrLeft0 = oldCtrl[ctrlNo].Left;
                    ctrTop0 = oldCtrl[ctrlNo].Top;
                    ctrWidth0 = oldCtrl[ctrlNo].Width;
                    ctrHeight0 = oldCtrl[ctrlNo].Height;
                    ctrFontSize0 = oldCtrl[ctrlNo].FontSize;
                    //设置控件新的位置和大小信息。
                    c.Left = (int)((ctrLeft0) * wScale);//新旧控件之间的线性比例。控件位置只相对于窗体
                    c.Top = (int)((ctrTop0) * hScale);//
                    c.Width = (int)(ctrWidth0 * wScale);//只与最初的大小相关,所以不能与现在的宽度相乘 
                    c.Height = (int)(ctrHeight0 * hScale);//
                    c.Font = new Font(c.Font.Name, (float)(ctrFontSize0 * wScale));//设置控件中字体的大小以适应控件的大小
                    ctrlNo++;//累加序号
                    //**放在这里,是先缩放控件本身,后缩放控件的子控件,重点是前后要一致(与保存时)
                    if (c.Controls.Count > 0)
                        AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
                }
            }
        }
    }
        代码中的注释比较详细了,如果你想实现窗体的自适应分辨率,你只需要在窗体的Layout事件中添加如下代码:
            /// <summary>
            /// 声明一个窗体自适应分辨率类
            /// </summary>
            public AutoSizeFormClass As = new AutoSizeFormClass();
            /// <summary>
            /// 在窗体的layout事件中调用
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Layout(object sender, LayoutEventArgs e)
            {
                As.controlAutoSize(this);
            }

        最后想说的是为什么用layout事件,不用Resize或者是SizeChanged事件,这个我查了好长时间,也自己试了所有的方法,但还是没能明白只是发现这几个事件的触发顺序是不同的首先触发的是Resize→然后是SizeChanged→然后是layout→最后是Load事件,是不是把适应分辨率的代码写在那个事件下都可以呢,这个我也尝试了,当窗体中含有tabcontrol控件时只有layout事件触发时才能检测出窗体中包含控件,这几个事件的区别我实在不知道有声明区别。希望读者给出帮助。




    展开全文
  • 转载,原文链接改进C# WinForm窗体及其控件的自适应 按下面的四步走,直接将代码复制到 public partial class Form1 : Form {在此粘贴代码},即可实现控件自适应窗口的效果 //默认主窗口类名称为Form1,在此添加...
  • 我们自己编写程序的界面,会遇到各种屏幕分辨率,只有自适应才能显的美观。实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比例变化即可。...
  • C# Winform自适应分辨率的类

    千次阅读 热门讨论 2013-02-20 22:19:57
    在做YH的时候,为了扩展界面的功能区域,...改回去太麻烦了,只好写了一个自适应分辨率的类,来解决这一问题。 多的不说了,直接上代码吧。 using System; using System.Collections.Generic; using System
  • 特别注意的是:在显示设置中的文本大小应该为100%,否则虽然你代码写分辨率,不管是写死还是读xml,效果与你预测的不一样。
  • 我们自己编写程序的界面,会遇到各种屏幕分辨率,只有自适应才能显的美观。实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比例变化即可。...
  • 1 近期做项目时,遇到开发的winform在自己电脑上可以正常显示,共享到其他电脑就事儿不能显示了: 2 3 1.当两个电脑分辨率相同时,无法显示完全,请检查form的autoscalemode属性是否为none,并设为none 4 ...
  • Winform 界面布局详解

    2013-05-16 18:13:04
    利用Dock Anchor 实现Winform 界面布局 和自适应
  • 1.界面自适应代码 在Form类文件中 全局变量X,Y private float X; private float Y; 具体的控件自适应方法 private void setTag(Control cons) { foreach (Control con in cons.Controls) { con.Tag = con....
  • private void SubForm_Load(object sender, EventArgs e) { this.WindowState = FormWindowState.Maximized; } 这句代码写在子窗体里可以让子窗体自适应父窗体大小 ...
  • winform 自适应屏幕分辨率

    千次阅读 2014-04-09 15:11:27
    比如panel不要和控件放在一层,panel与panel之间使用dock属性排好,除非特殊需求一般不要对非容器性控件直接使用dock,form界面设计不像一个函数一样是什么功能就是什么功能,没有一个可以应用于所有form 的设计...
  • 1、加工程中加入AutoSizeFormClass.cs 2、把窗口属性WindowState改为Maximized 3、窗口中如果有panel则把的属性AutoSize改为TRUE 4、在窗口构造函数中实例化对象 AutoSizeFormClass asc = new AutoSizeFormClass();...
  • //递归函数调用,防止遗漏嵌套的控件(如:Group、Panel等) } } } // 窗体自适应分辨率 public void ControlAutoSize(Control MainForm) { if (CtrNo == 0) { ControlProperty Ctp = new ControlProperty();...
  • C#winform 窗体缩放自适应

    千次阅读 2018-09-10 11:14:00
    1. 首先在窗体上放上一个Panel容器,并将容器的Dock属性设为Fill,即所有的控件都放在了这个容器里。 using System; using System.Collections.Generic; ...using System.Drawing;...namespace Window...
  • 使用SmartPhone上的WinForm做了一个WM的小程序,结果放到手机上实际一运行。发现动态生成的控件在里面显示得都非常小,难以看清。 原因 我的问题是需要在InitializeComponent方法结束后,动态生成一些控件,...
  • namespace Test_Tank_Scout { public class exe2Winform { #region 字段 /* Application.Idle:当应用程序完成处理并即将进入空闲状态时发生 -->appIdleEvent:要处理的事件 -->订阅了Application_Idle:确保应用...
  • WinForm窗体及其控件的自适应,对于容器内的控件同样有效
  • 最近在开发一个c/s软件,结果发现软件在本机和客户端上的显示大相径庭。在本机上显示佷规整,但在客户机上控件显示时都缩了一些...整个软件界面布局很不美观,原因是客户机上的分辨率要高。请问这种问题如何能解决呢?
  • 1.项目情况:项目使用winform搭建,禁用用户放大缩小,一直全屏展示 2.问题: a.用tableLayoutPanel加panel能不能做到自适应布局呢?(保证布局不跑偏) b.如果a成立那么里面的控件如何做到按照屏幕分辨率等比缩放呢,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 563
精华内容 225
关键字:

winform界面自适应