目录
前言
写这篇文章,主要是我发现自己的界面太丑了,我受不了。而且项目运行后,winform窗口是窗口,放大后又是另一种样子,丑到家了。
一、自适应布局
step1. 添加autoadaptwindowssize类
- 做法:将form装入panel容器中。在项目中添加autoadaptwindowssize.cs类。代码见下图【直接复制类中内容即可,添加的类名重命名为autoadaptwindowssize.cs】
- 优点:不用在form中添加任何布局,直接将类复制到项目中,在form代码中调用即可,页面大小会自动计算,修改方便,速度块。
- 缺点:form中的背景图片会直接显示成纯图的背景。【autoadaptwindowssize类中会创建一个panel,panel背景会自动设置,而pannel的纯色背景会覆盖掉form的背景。】
internal class autoadaptwindowssize
{
double formoriginalwidth;//窗体高度原始宽度
double formoriginalheight;//窗体原始
double scalex;//水平缩放比例
double scaley;//垂直缩放比例
dictionary<string, string> controlsinfo = new dictionary<string, string>();//控件中心left,top,控件width,控件height,控件字体size
private form _form;
panel win_panel1 = new panel();
public autoadaptwindowssize(form form)
{
_form = form;
//代码生成一个容器panel1,添加至窗体
_form.controls.add(win_panel1);
win_panel1.borderstyle = borderstyle.none; //容器border样式
win_panel1.dock = dockstyle.fill; //设置填充,下面添加控件至容器完成后,容器会填充窗口
win_panel1.backcolor = color.transparent; // 这里默认的背景颜色是form的背景颜色,如果form页面时图片,需要将这里的颜色设置成透明,否则会被覆盖。
//将窗体所有控件添加至panel1
while (_form.controls[0].name.trim() != "")
{
foreach (control item in _form.controls)
{
if (item.name.trim() != "" && item.name.trim() != win_panel1.name.trim())
{
win_panel1.controls.add(item);
}
}
}
//保存窗体和控件初始大小
initcontrolsinfo(win_panel1);
}
public void initcontrolsinfo(control ctrlcontainer)
{
if (ctrlcontainer.parent == _form)//获取窗体的高度和宽度
{
formoriginalwidth = convert.todouble(ctrlcontainer.width);
formoriginalheight = convert.todouble(ctrlcontainer.height);
}
foreach (control item in ctrlcontainer.controls)
{
if (item.name.trim() != "")
{
//添加信息:键值:控件名,内容:据左边距离,距顶部距离,控件宽度,控件高度,控件字体。
controlsinfo.add(item.name, (item.left + item.width / 2) + "," + (item.top + item.height / 2) + "," + item.width + "," + item.height + "," + item.font.size);
}
if ((item as usercontrol) == null && item.controls.count > 0)
{
initcontrolsinfo(item);
}
}
}
public void formsizechanged()
{
try
{
if (controlsinfo.count > 0)//如果字典中有数据,即窗体改变
{
controlszoomscale(win_panel1);//表示pannel控件
controlschange(win_panel1);
}
}
catch { }
}
private void controlszoomscale(control ctrlcontainer)
{
scalex = (convert.todouble(ctrlcontainer.width) / formoriginalwidth);
scaley = (convert.todouble(ctrlcontainer.height) / formoriginalheight);
}
/// <summary>
/// 改变控件大小
/// </summary>
/// <param name="ctrlcontainer"></param>
private void controlschange(control ctrlcontainer)
{
double[] pos = new double[5];//pos数组保存当前控件中心left,top,控件width,控件height,控件字体size
foreach (control item in ctrlcontainer.controls)//遍历控件
{
if (item.name.trim() != "")//如果控件名不是空,则执行
{
if ((item as usercontrol) == null && item.controls.count > 0)//如果不是自定义控件
{
controlschange(item);//循环执行
}
string[] strs = controlsinfo[item.name].split(',');//从字典中查出的数据,以‘,’分割成字符串组
for (int i = 0; i < 5; i++)
{
pos[i] = convert.todouble(strs[i]);//添加到临时数组
}
double itemwidth = pos[2] * scalex; //计算控件宽度,double类型
double itemheight = pos[3] * scaley; //计算控件高度
item.left = convert.toint32(pos[0] * scalex - itemwidth / 2);//计算控件距离左边距离
item.top = convert.toint32(pos[1] * scaley - itemheight / 2);//计算控件距离顶部距离
item.width = convert.toint32(itemwidth);//控件宽度,int类型
item.height = convert.toint32(itemheight);//控件高度
if (float.parse((pos[4] * math.min(scalex, scaley)).tostring()) != 0) //缩放字体大小不能为0
{ item.font = new font(item.font.name, float.parse((pos[4] * math.min(scalex, scaley)).tostring())); } //字体
}
}
}
}
step2. form中引用
引用:【这个是因为我将autoadaptwindowssize.cs放在manager文件夹下了】
using thinger.projectdemo.manager;
创建全局变量
autoadaptwindowssize autosize;
在form_load添加如下代码,在界面初始化的过程中创建autosize。
private void frmmain_load(object sender, eventargs e)
{
autosize = new autoadaptwindowssize(this);
}
step3. 创建sizechanged事件函数
private void frmmain_sizechanged(object sender, eventargs e)
{
if (autosize != null) // 这个判断防止电脑缩放的布局不是100%时候的报错。
{
autosize.formsizechanged();
}
}
step4. 在fram.disiger中添加
为了解决拖动窗口时出现的严重闪屏现象。disiger位置:
代码如下:
using system.windows.forms;
protected override createparams createparams
{
get
{
createparams cp = base.createparams;
cp.exstyle |= 0x02000000;
return cp;
}
}
更新时间
- 2024.07.19
发表评论