WinForm由于Windows缩放功能造成界面大小、对齐均错误

Diao_Wang 上海应用技术大学 Student  2017-11-22 09:24:26
首先,我使用的笔记本屏幕17英寸2560*1440,Windows文本缩放到150刚好满足使用,100%会让字小的没有办法使用电脑。
然后在此条件下使用VS2015,问题就出现了。
在设计界面内一切正常



但默认情况下打开或者直接使用VS2015的调试运行程序,界面会变得很大,而且控件偏左


然后我在程序属性的兼容性中设置了缩放行为-应用程序

这样在我本机上,设置过缩放属性的程序打开时界面会变成正常状态,与设计界面上的相同。



但当我在其他使用独立显示器的电脑,Windows缩放为100%时 变大的界面和控件偏左的情况再次出现


此时无论怎样都没有办法变为如窗体设计器中的样子。程序属性兼容性设置中的禁用高DPI缩放设置已经没有效果。

只有将其他电脑的缩放设置为同我写程序的电脑相同的150%,并且勾上高DPI时禁用缩放选项,才能再次恢复正常。






100%缩放环境的图片为了方便使用了虚拟机截图,在同学电脑上也测试了存在相同问题。

本人只是大专软件专业学生,最近布置大作业,期末需要在学校机器展示,测试中才注意到这个问题,因为我们课上所讲内容实在有限,没有提过相关问题的处理方法,在尝试百度上多种针对WinForm的HiDPI缩放处理方法后仍没有达到我需要的效果。

我不要这个程序多完美,机房电脑都是1366*768的低分辨率显示器,完全不需要适配高分屏,只是希望他在所有电脑上都禁用DPI感知(不知道是否准确,查资料过程中找到DPI aware这个词),只要和我设计的界面一样不要错乱就行。我的电脑如果用100%缩放字都看不清,真的难以使用。。。

希望能在此处找到有效的解决办法!


...全文
1656 19 1 打赏 收藏 举报
写回复
19 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
bbjiabcd 2017-12-01
精选
你在做程序的时候必须使用100%缩放,否则在其他机器上容易出问题的。 如果100%会让字小的没有办法使用电脑,则需调整降低你自己电脑的分辨率,使其在100%缩放的情况下看得清。 只有在100%缩放做好程序之后,再考虑不同DPI情况下 显示不正常如何调整。
  • 打赏
  • 举报
回复 2
引用 14 楼 xomix 的回复:
[quote=引用 9 楼 ooo88888888ooo 的回复:] [quote=引用 5 楼 xomix 的回复:] [quote=引用 4 楼 sp1234 的回复:] 如果你想开发比较好的响应式前端界面程序,学习 web 前端开发。winform 控件体系整体比较古老,不行。
如果就这几个窗口,也不是不行的,你不能一口就否认。 方法1:在创建窗口之前使用窗口的信息再创建一个同样窗口但是不显示,这样就能获取到不论什么dpi下窗口内元素的大小和窗口大小,然后根据元素大小和窗口大小动态计算居中后重新排列窗口内元素位置。动态计算位置的时候注意一下窗口的标题栏。 方法2:看看禁用dpi缩放配置是保存在系统什么位置(注册表几率很大),简单解析一下配置信息,打包程序的时候打包配置,写入系统。 如果只要“不要这个程序多完美,机房电脑都是1366*768的低分辨率显示器,完全不需要适配高分屏,只是希望他在所有电脑上都禁用DPI感知(不知道是否准确,查资料过程中找到DPI aware这个词),只要和我设计的界面一样不要错乱就行。”这个需求,这两个方法都可以完美实现。[/quote] 方法2我怕是实现不了,我们根本没学过打包。。都直接提交解决方案,请问方法1能否讲解详细一些?如何根据元素大小和窗口大小动态计算重新排列??或者相关讲解的链接??或者我应该搜索哪些关键字??[/quote]

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 测试集合
{
    public partial class Form2 : Form
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(746, 419);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(12, 9);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(46, 17);
            this.label1.TabIndex = 1;
            this.label1.Text = "label1";
            // 
            // Form2
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(833, 454);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.button1);
            this.Name = "Form2";
            this.Text = "Form2";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.PictureBox pictureBox1;

        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Random r = new Random(DateTime.Now.Second);
            int j=r.Next(1,30);
            string labletxt = "test".PadLeft(j, 'Z');
            label1.Text = labletxt;
            label1.Left = (this.Width - label1.Width) / 2; 
        }


    }
}
你运行看看,这就是lable自动居中的计算方法。 有时候有些事比你想得简单多了。 如果你觉得这样做太麻烦,直接做成图片更简单更快速。[/quote] label1.Left = (this.Width - label1.Width) / 2; 这个计算方法好用
  • 打赏
  • 举报
回复
assky124 2017-11-27
不想缩放 Form 的 AutoScaleMode = None 缩放后自动居中TableLayout就可以了,不用自己算。(其实自己算最好,少一些控件)
  • 打赏
  • 举报
回复
小大飞 2017-11-27
666绑定,不懂这个东西
  • 打赏
  • 举报
回复
Diao_Wang 2017-11-26
引用 12 楼 qq_25095899 的回复:
wpf grid布局牛批的一瞥,不过楼主既然已经选择了winform,那么楼上几位,包括我,说的都是废话了。
我知道WPF好,只是我们课程内并没有讲过WPF(估计也不会讲),这种期末作业我不认为我现学现卖就能做好呀。。
  • 打赏
  • 举报
回复
xuzuning 2017-11-24
load 事件里重新计算控件的相对定位 而不是仅通过可视化工具的拖拽定位,因为拖拽后是以绝对定位保存的 比如 this.label1.Location = new System.Drawing.Point(12, 9);
  • 打赏
  • 举报
回复
引用 9 楼 ooo88888888ooo 的回复:
[quote=引用 5 楼 xomix 的回复:] [quote=引用 4 楼 sp1234 的回复:] 如果你想开发比较好的响应式前端界面程序,学习 web 前端开发。winform 控件体系整体比较古老,不行。
如果就这几个窗口,也不是不行的,你不能一口就否认。 方法1:在创建窗口之前使用窗口的信息再创建一个同样窗口但是不显示,这样就能获取到不论什么dpi下窗口内元素的大小和窗口大小,然后根据元素大小和窗口大小动态计算居中后重新排列窗口内元素位置。动态计算位置的时候注意一下窗口的标题栏。 方法2:看看禁用dpi缩放配置是保存在系统什么位置(注册表几率很大),简单解析一下配置信息,打包程序的时候打包配置,写入系统。 如果只要“不要这个程序多完美,机房电脑都是1366*768的低分辨率显示器,完全不需要适配高分屏,只是希望他在所有电脑上都禁用DPI感知(不知道是否准确,查资料过程中找到DPI aware这个词),只要和我设计的界面一样不要错乱就行。”这个需求,这两个方法都可以完美实现。[/quote] 方法2我怕是实现不了,我们根本没学过打包。。都直接提交解决方案,请问方法1能否讲解详细一些?如何根据元素大小和窗口大小动态计算重新排列??或者相关讲解的链接??或者我应该搜索哪些关键字??[/quote]

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 测试集合
{
    public partial class Form2 : Form
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(746, 419);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(12, 9);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(46, 17);
            this.label1.TabIndex = 1;
            this.label1.Text = "label1";
            // 
            // Form2
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(833, 454);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.button1);
            this.Name = "Form2";
            this.Text = "Form2";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.PictureBox pictureBox1;

        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Random r = new Random(DateTime.Now.Second);
            int j=r.Next(1,30);
            string labletxt = "test".PadLeft(j, 'Z');
            label1.Text = labletxt;
            label1.Left = (this.Width - label1.Width) / 2; 
        }


    }
}
你运行看看,这就是lable自动居中的计算方法。 有时候有些事比你想得简单多了。 如果你觉得这样做太麻烦,直接做成图片更简单更快速。
  • 打赏
  • 举报
回复
耗子哭死猫 2017-11-24
Form1 f = new Form1(); f.StartPosition = FormStartPosition.CenterScreen; 放了load事件中,运行后加载窗体居中
  • 打赏
  • 举报
回复
大然然 2017-11-24
wpf grid布局牛批的一瞥,不过楼主既然已经选择了winform,那么楼上几位,包括我,说的都是废话了。
  • 打赏
  • 举报
回复
exception92 2017-11-24
WPF要解决桌面程序的部分问题 就是楼主所描述的。WPF中的布局结构非常灵活,各种面板的使用也很容易上手,缩放更加容易,使用一个名为ViewBox的控件就可以很容易解决问题。 布局合理,控件对齐方式设置好,完全不用担心控件错位。
用winform来做局限性太大,即使使用layout,部分dock机制也避免不了出现布局问题。
  • 打赏
  • 举报
回复
assky124 2017-11-24
用WPF就很简单了 WINFORM的话,试试用TableLayout布局;设置窗体字体不缩放,然后根据窗体大小,动态设置下字体
  • 打赏
  • 举报
回复
而且lz的问题还有一个最快捷的解决方案,把所有文字都转换为图片,然后放在按钮上zoom…………
  • 打赏
  • 举报
回复
引用 4 楼 sp1234 的回复:
如果你想开发比较好的响应式前端界面程序,学习 web 前端开发。winform 控件体系整体比较古老,不行。
甚至于,利用user32.dll的接口,是完全可以获取到dpi缩放的情况的,这种时候完全可以按照dpi缩放的数值直接计算控件位置。 http://blog.csdn.net/kkbinkbi/article/details/67636930 直接抛弃旧的技术和一些方法,这也是一个不好的习惯。 是的,客户有时确实有这样的奇怪需求,这没什么好奇怪的。
  • 打赏
  • 举报
回复
引用 4 楼 sp1234 的回复:
如果你想开发比较好的响应式前端界面程序,学习 web 前端开发。winform 控件体系整体比较古老,不行。
如果就这几个窗口,也不是不行的,你不能一口就否认。 方法1:在创建窗口之前使用窗口的信息再创建一个同样窗口但是不显示,这样就能获取到不论什么dpi下窗口内元素的大小和窗口大小,然后根据元素大小和窗口大小动态计算居中后重新排列窗口内元素位置。动态计算位置的时候注意一下窗口的标题栏。 方法2:看看禁用dpi缩放配置是保存在系统什么位置(注册表几率很大),简单解析一下配置信息,打包程序的时候打包配置,写入系统。 如果只要“不要这个程序多完美,机房电脑都是1366*768的低分辨率显示器,完全不需要适配高分屏,只是希望他在所有电脑上都禁用DPI感知(不知道是否准确,查资料过程中找到DPI aware这个词),只要和我设计的界面一样不要错乱就行。”这个需求,这两个方法都可以完美实现。
  • 打赏
  • 举报
回复
根本不应该考虑“缩放”,按照正常情况编程开发就好。
  • 打赏
  • 举报
回复
易2017 2017-11-23
可以了解下WPF的分辨率无关特性
  • 打赏
  • 举报
回复
cyg17173 2017-11-23
同问,属于先天不足,貌似没有好办法,一般人都说使用WPF解决,但是现在都2017年了,建议可以考虑学习uwp 。
  • 打赏
  • 举报
回复
Diao_Wang 2017-11-23
引用 5 楼 xomix 的回复:
[quote=引用 4 楼 sp1234 的回复:] 如果你想开发比较好的响应式前端界面程序,学习 web 前端开发。winform 控件体系整体比较古老,不行。
如果就这几个窗口,也不是不行的,你不能一口就否认。 方法1:在创建窗口之前使用窗口的信息再创建一个同样窗口但是不显示,这样就能获取到不论什么dpi下窗口内元素的大小和窗口大小,然后根据元素大小和窗口大小动态计算居中后重新排列窗口内元素位置。动态计算位置的时候注意一下窗口的标题栏。 方法2:看看禁用dpi缩放配置是保存在系统什么位置(注册表几率很大),简单解析一下配置信息,打包程序的时候打包配置,写入系统。 如果只要“不要这个程序多完美,机房电脑都是1366*768的低分辨率显示器,完全不需要适配高分屏,只是希望他在所有电脑上都禁用DPI感知(不知道是否准确,查资料过程中找到DPI aware这个词),只要和我设计的界面一样不要错乱就行。”这个需求,这两个方法都可以完美实现。[/quote] 方法2我怕是实现不了,我们根本没学过打包。。都直接提交解决方案,请问方法1能否讲解详细一些?如何根据元素大小和窗口大小动态计算重新排列??或者相关讲解的链接??或者我应该搜索哪些关键字??
  • 打赏
  • 举报
回复
Diao_Wang 2017-11-23
引用 3 楼 sp1234 的回复:
根本不应该考虑“缩放”,按照正常情况编程开发就好。
问题是这样呀,这个软件的现状是在我自己机器不设置禁用高DPI缩放界面都是有问题的。然后大作业要作为期末考评的一部分在学校机器演示,这种错位的界面肯定会丢分。。。请您仔细看第四个和第六个截图,不正常时窗体的大小都是有问题的。 最后即便我无视他的错位,功能实现都正确,演示时老师要求的【界面美观】上一定要丢分的。。
  • 打赏
  • 举报
回复
相关推荐
发帖
C#
加入

10.6w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2017-11-22 09:24
社区公告

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