[分享]做一做,winfrom 窗体程序 自动缩放

非专业开发Five 2018-03-22 01:38:20
加精
每隔几个月,总有那么几个人,发现winfrom的窗体缩放不尽人意,在自己电脑上开发时很好的界面到了客户电脑上分辨率不一样看起来稀奇古怪的。

我也回答过很多次这种帖子,也做出来过半成品的左上角缩放的代码。但是都不完美。

今天又看到一个4k屏觉得窗体小的,我当时的感觉是“妈的!有钱人!开发都4k屏了!!!”,但是这让我想,能不能从根本上想个办法解决缩放的问题呢?

所以我就想到了最初写的那篇左上角缩放的代码,我在想不完美的地方在哪里?

看看图,可以看出由于原点坐标的错位,导致缩放后的控件头部偏移了。

这就产生了现在的解决方案:重新定位原点缩放控件(窗口)。

所以使用了最简单的方法,将整个控件(是的窗体也是控件)的中心点作为原点,利用现有坐标重新求出子控件坐标集合。

并且将子空间的大小重新用和父控件坐标比的形式计算。(我总觉得用不着,不过我觉得在有些特殊比例的时候这样做一下似乎比直接缩放会多一点兼容性。)

重新计算全部子控件的位置和大小,最后改变控件本身大小。

做完试了一下,效果不错,不过缩小的时候有几率把子控件丢到控件显示范围外,我并没有修复这个bug。

好啦下面是代码,我注释写的也比较详细,有相关需要的人可以直接拿去用了。

代码写得很烂,很多比如结构化那里,我本来是用的系统 Point 和 Size 但是因为int不能满足缩放计算的各种需求所以就用了很多c#自动生成的部分,代码中变量的生命周期我也没有做任何规划,这些都可以完善,拿个半成品玩具出来,给大家开拓点思维吧。

当然这不完善的地方还有很多,比如不支持非控件的调整等。我回头有时间开个GitHub坑好了。

private void ZoomEX(System.Windows.Forms.Control c, int Zoom)
{

//求出相对中心
System.Drawing.Point p0 = new System.Drawing.Point(c.Width / 2, c.Height / 2);
//获取控件列表,计算控件距离中心位置得出相对坐标。
System.Collections.Generic.LinkedList<ControlEx> Controls
= new System.Collections.Generic.LinkedList<ControlEx>();
foreach (System.Windows.Forms.Control item in c.Controls)
{
//查看该控件是否有子控件,如果有,便利子控件自调用本方法
if (item.HasChildren)
{
ZoomEX(item, Zoom);
}
ControlEx itemEx = new ControlEx(item);
itemEx.ExPoint = new ControlEx.exPoint(((float)item.Left - (float)p0.X) / (float)c.Width, ((float)item.Top - (float)p0.Y) / (float)c.Height);
itemEx.ExSize = new ControlEx.exSize((float)item.Width / (float)c.Width, (float)item.Height / (float)c.Height);
Controls.AddLast(itemEx);
}
//控件根据zoom重新缩放
System.Drawing.Size newSize = new System.Drawing.Size(c.Width * Zoom / 10, c.Height * Zoom / 10);
//求出新的相对中心
System.Drawing.Point pNew = new System.Drawing.Point(newSize.Width / 2, newSize.Height / 2);
//对每一个控件重新生成坐标
foreach (ControlEx item in Controls)
{
item.Control.Size = new System.Drawing.Size((int)(item.ExSize.Width * newSize.Width), (int)(item.ExSize.Height * newSize.Height));
item.Control.Location = new System.Drawing.Point((int)(item.ExPoint.X * newSize.Width + pNew.X), (int)(item.ExPoint.Y * newSize.Height + pNew.Y));
}
c.Size = newSize;//重置控件本身大小
}

class ControlEx
{
public System.Windows.Forms.Control Control { get; set; }
public ControlEx(System.Windows.Forms.Control c)
{
Control = c;
}
public exPoint ExPoint { get; set; }
public exSize ExSize { get; set; }
public class exPoint
{
public float X;
public float Y;

public exPoint(float x, float y)
{
// TODO: Complete member initialization
this.X = x;
this.Y = y;
}
}
public class exSize {
public exSize(float p1, float p2)
{
// TODO: Complete member initialization
this.Width = p1;
this.Height = p2;
}
public float Width { get; set; }
public float Height { get; set; }
}
}

//窗体使用 ZoomEX(this, 5); 实现缩放,1.0
...全文
7351 49 打赏 收藏 转发到动态 举报
写回复
用AI写文章
49 条回复
切换为时间正序
请发表友善的回复…
发表回复
skil35 2020-03-11
  • 打赏
  • 举报
回复
感谢楼主无私分享
Jeromeyoung666 2018-07-21
  • 打赏
  • 举报
回复
其实涉及到缩放,那考虑的就该全面点。比如:像素、比例、对接等等,别把缩放当做小事,应用前途也很广。到产业中,也是一个比较有潜力的方面,当然娱乐占很大一方面。
fuxiaoyang13 2018-07-21
  • 打赏
  • 举报
回复
多谢分享!!!!!
fanfan12121 2018-07-21
  • 打赏
  • 举报
回复
感谢分享 !!!!
smkl 2018-07-21
  • 打赏
  • 举报
回复
最近正好在玩winform看到就进来了
大莫子 2018-07-16
  • 打赏
  • 举报
回复
引用 21 楼 xuzuning 的回复:
没有一种可以及时解决问题的途径、方法或工具呢?有时完全找不到人帮忙
大莫子 2018-07-16
  • 打赏
  • 举报
回复
引用 11 楼 xuzuning 的回复:
X、Y 同比例缩放显然不能适应不同规格的屏幕需要
非要让喜欢 winform 的人换用 wpf 岂不比美国佬还霸道?
没有一种可以及时解决问题的途径、方法或工具呢?
大莫子 2018-07-16
  • 打赏
  • 举报
回复
引用 2 楼 hanjun0612 的回复:
可以让大家一起讨论。
多种方案和方案的优劣。
没有一种可以及时解决问题的途径、方法或工具呢?
qq_23236261 2018-07-11
  • 打赏
  • 举报
回复
怎么调用?Zoom值是代表什么?
正怒月神 2018-05-16
  • 打赏
  • 举报
回复
帮你结了,均5分。
  • 打赏
  • 举报
回复
@hanjun0612 求助版主我没法结帖。
大鱼> 2018-05-15
  • 打赏
  • 举报
回复
引用 18 楼 xuzuning 的回复:
和我之前给别人写的一个demo神似啊!
维秀斯丢丢 2018-05-15
  • 打赏
  • 举报
回复
4k下面,谁用过qq的,界面有多大?
健者天行 2018-04-25
  • 打赏
  • 举报
回复
引用 18 楼 xuzuning 的回复:
版主,你这个很6啊,有代码,可以贴出来学习一下吧。
pledgeslove 2018-04-22
  • 打赏
  • 举报
回复
这个不错正需要这个呢!
lalanbv 2018-04-20
  • 打赏
  • 举报
回复
这个很6啊,我感觉不错
l357630798 2018-04-14
  • 打赏
  • 举报
回复
没具体做过,感觉用布局控件就应该可以实现呢。但,至少使用布局可以实现同比例缩放控件、字体等功能。
l357630798 2018-04-14
  • 打赏
  • 举报
回复
用Layout容器控件不行吗?
跳动de指尖 2018-04-13
  • 打赏
  • 举报
回复
4k分辨率下,问题有点大
拜一刀 2018-04-04
  • 打赏
  • 举报
回复
有人让我做个触摸屏的程序,屏幕贼大,内容倒是简单 我选择cefsharp,然后做一套网页上去
加载更多回复(29)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧