博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# WinForm窗体及其控件自适应各种屏幕分辨率
阅读量:2119 次
发布时间:2019-04-30

本文共 5277 字,大约阅读时间需要 17 分钟。

转自http://www.verydemo.com/demo_c92_i8330.html

一。说明

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

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace WindowsApplication1{    public partial class Form1 : Form    {        //1.声明自适应类实例        AutoSizeFormClass asc = new AutoSizeFormClass();        public Form1()        {            InitializeComponent();        }        //2. 为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件的初始位置和大小        private void Form1_Load(object sender, EventArgs e)        {            asc.controllInitializeSize(this);        }        //3.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应        private void Form1_SizeChanged(object sender, EventArgs e)        {            asc.controlAutoSize(this);        }    }}
(二)。自适应类的代码

using System;using System.Collections.Generic;using System.Text;using System.Windows.Forms;namespace WindowsApplication1{    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; //int ctrl_first = 0; //(3). 创建两个函数 //(3.1)记录窗体和其控件的初始位置和大小, public void controllInitializeSize(Form mForm) { // if (ctrl_first == 0) { // ctrl_first = 1; oldCtrl = new List
(); controlRect cR; cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height; oldCtrl.Add(cR); foreach (Control c in mForm.Controls) { controlRect objCtrl; objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height; oldCtrl.Add(objCtrl); } } // this.WindowState = (System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化 //0 - Normalize , 1 - Minimize,2- Maximize } //(3.2)控件自适应大小, public void controlAutoSize(Form mForm) { //int wLeft0 = oldCtrl[0].Left; ;//窗体最初的位置 //int wTop0 = oldCtrl[0].Top; int wLeft1 = this.Left;//窗体当前的位置 //int wTop1 = this.Top; float wScale = (float)mForm.Width / (float)oldCtrl[0].Width;//新旧窗体之间的比例,与最早的旧窗体 float hScale = (float)mForm.Height / (float)oldCtrl[0].Height;//.Height; int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0; int ctrlNo = 1;//第1个是窗体自身的 Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始 foreach (Control c in mForm.Controls) { 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 += 1; } } }}
当然,窗口坐标和屏幕坐标也是可以相互转换的:

private void Form1_MouseDown(object sender, MouseEventArgs e){   int x = e.X; //相对form窗口的坐标,客户区坐标   int y = e.Y;   int x1 = Control.MousePosition.X;//相对显示器,屏幕的坐标   int y1 = Control.MousePosition.Y;  }
它们之间转换如下:
this.Location; // 窗体所在坐标
this.PointToScreen(new Point(0, 0)); // 客户区坐标转换为屏幕坐标

this.PointToClient(new Point(0, 0)); // 屏幕坐标转换为客户区坐标

=========================================================

另:利用Anchor和Dock属性控制位置

Anchor属性
控件将其自身定位在父窗体或父控件中的某个相对或绝对位置。这个属性有四个可以开启或关闭的值:
    Top——表示控件中与父窗体(或父控件)相关的顶部应该保持固定。
    Bottom——表示控件中与父窗体(或父控件)相关的底边应该保持固定。
    Left——表示控件中与父窗体(或父控件)相关的左边缘应该保持固定。
    Right——表示控件中与父窗体(或父控件)相关的右边缘应该保持固定。
当选择了所有的anchor值时,控件只是在调整父窗体大小时,随着增大和收缩——与窗体的边缘比较起来它的所有边缘保持静止不变。
Dock属性
使控件紧贴父窗体(或控件)的某个边缘。虽然Anchor属性也可以实现这一点,但是dock属性使得你能够在父窗体中让子窗体可以在上方(或旁边)互相“堆叠”。如果某个子窗体改变了大小,其它停驻在它旁边的子窗体也会随之改变。
和Anchor属性不同的是,你可以将Dock属性设置为一个单值。有效值如下所示:
    Top——迫使控件位于父窗体(或控件)的顶部。如果有同一个父窗体的其它子控件也被设置为停驻在顶部的话,那么控件将在彼此上方相互堆叠。
    Bottom——迫使控件位于父窗体(或控件)的底部。如果有同一个父窗体的其它子控件也被设置为停驻在底部的话,那么控件将在彼此上方相互堆叠。
    Left——迫使控件位于父窗体(或控件)的左边。如果有同一个父窗体的其它子控件也被设置为停驻在左边的话,那么控件将在彼此旁边相互堆叠。
    Right——迫使控件位于父窗体(或控件)的右边。如果有同一个父窗体的其它子控件也被设置为停驻在右边的话,那么控件将在彼此旁边相互堆叠。
    Fill——迫使控件位于父窗体(或控件)的上方。如果有同一个父窗体的其它子控件也被设置为停驻在上方的话,那么控件将在彼此上方相互堆叠。
    None——表示控件将会正常运转。

转载地址:http://lmzrf.baihongyu.com/

你可能感兴趣的文章
算法导论阅读顺序
查看>>
Windows程序设计:直线绘制
查看>>
linux之CentOS下文件解压方式
查看>>
Django字段的创建并连接MYSQL
查看>>
div标签布局的使用
查看>>
HTML中表格的使用
查看>>
(模板 重要)Tarjan算法解决LCA问题(PAT 1151 LCA in a Binary Tree)
查看>>
(PAT 1154) Vertex Coloring (图的广度优先遍历)
查看>>
(PAT 1115) Counting Nodes in a BST (二叉查找树-统计指定层元素个数)
查看>>
(PAT 1143) Lowest Common Ancestor (二叉查找树的LCA)
查看>>
(PAT 1061) Dating (字符串处理)
查看>>
(PAT 1118) Birds in Forest (并查集)
查看>>
数据结构 拓扑排序
查看>>
(PAT 1040) Longest Symmetric String (DP-最长回文子串)
查看>>
(PAT 1145) Hashing - Average Search Time (哈希表冲突处理)
查看>>
(1129) Recommendation System 排序
查看>>
PAT1090 Highest Price in Supply Chain 树DFS
查看>>
(PAT 1096) Consecutive Factors (质因子分解)
查看>>
(PAT 1019) General Palindromic Number (进制转换)
查看>>
(PAT 1073) Scientific Notation (字符串模拟题)
查看>>