简介:有很多评论说"WinForms不能自动扩展到DPI /字体设置;切换到WPF".但是,我认为这是基于.NET 1.1; 看起来他们在.NET 2.0中实现自动扩展实际上做得非常好.至少基于我们迄今为止的研究和测试.但是,如果你们中的一些人知道的更好,我们很乐意听取你的意见.(请不要打扰我们应该切换到WPF ...现在不是一个选项.)
WinForms中的内容不能正确自动缩放,因此应该避免?
编写WinForms代码时程序员应遵循哪些设计指南,以便自动扩展?
请参阅下面的社区维基答案.
这些是不正确还是不充分?我们应采用的其他指导方针?是否还有其他需要避免的模式?对此的任何其他指导将非常感激.
我在C#中创建了一个简单的Winforms应用程序.当我在具有高DPI设置(例如150%)的计算机上运行应用程序时,应用程序会按比例放大.到现在为止还挺好!但是,不是使用更高的字体大小渲染字体,所有文本也只是按比例放大.这当然导致非常模糊的文本(在按钮等所有控件上).
窗户不应该正确地渲染文本吗?例如,我的应用程序的标题栏呈现清晰明了.
我为小型企业创建了一个应用程序.办公室的一些员工无法正确查看表格.原因是他们的DPI设置设置为96dpi以上.有人知道控制这个的方法吗?
对于有winforms应用程序经验的所有人,如何控制表单布局以使DPI不影响应用程序的外观?
我的应用程序在100%DPI设置下看起来很好,但是当用户选择不同的(125%或150%)单词时,不适合容器.我尝试用我在这里找到的解决方案解决这个问题:检测Windows字体大小(100%,125%,150%),这是:
this.AutoScaleMode = AutoScaleMode.Dpi;
Run Code Online (Sandbox Code Playgroud)
它固定了150%的设置(使它有点模糊,但没关系),不幸的是它没有使用125%,这是在应用程序打算运行的PC上使用.
是否有一些简单的解决方法,或者我必须手动重新排列每个表单?
我正在使用VSTO构建办公室插件.在具有不同DPI设置的多个监视器的系统上,我的自定义任务窗格的内容在具有较高DPI设置的监视器上绘制两次:
只有较小的版本实际上响应用户输入.较大的版本似乎只是一个放大的图像.
我尝试过使用各种DPI相关设置,例如:
AutoScaleMode
在我的用户控制上.我尝试了所有选项,没有变化.SetProcessDpiAwareness
.我尝试了所有选项,没有变化.dpiAware
为true
和false
.没变.新的Web Addins没有这个问题.此外,内部任务窗格没有此问题.
这是一个已知的问题吗?我怎样才能解决这个问题?
情况
我们正在向全世界的客户销售Windows Forms应用程序.我们在欧洲和美国的几个国家安装了它.没问题.上周我们在韩国安装了我们的软件并认识到了一种奇怪的行为......
问题仅发生在客户办公室PC上,而是发生在所有客户办公室PC上.有些有Windows 7 Professional K,有些有Windows XP.
客户购买了一台安装了Windows 7旗舰版的新PC.在这台电脑上,没有问题.
功能
我们的应用程序中的所有元素都源自提供特殊功能的"父级用户控件".其中一个功能是"自动调整和定位".当父级更改大小时,将调用所有子级的此函数.
当我们的应用程序启动时,我们存储"ClientSize":
InitializeComponent();
this.m_actSize = this.ClientSize;
Run Code Online (Sandbox Code Playgroud)
每当应用程序的大小发生变化时,我们计算缩放因子并用它引发一个事件:
void myFormSizeChanged(object sender, EventArgs e)
{
this.m_xFactor = (float)this.ClientSize.Width / (float)this.m_actSize.Width;
this.m_yFactor = (float)this.ClientSize.Height / (float)this.m_actSize.Height;
if (this.m_MyOnResize != null)
this.m_MyOnResize(this.m_xFactor, this.m_yFactor);
}
Run Code Online (Sandbox Code Playgroud)
现在,每个订阅的孩子都会执行自动调整大小和定位:
void MyParentUserControl_MyOnResize(float v_xFactor, float v_yFactor)
{
this.Location = new Point((int)(this.m_actLocation.X * v_xFactor), (int)(this.m_actLocation.Y * v_yFactor));
this.Size = new Size((int)(this.m_actSize.Width * v_xFactor), (int)(this.m_actSize.Height * v_yFactor));
}
Run Code Online (Sandbox Code Playgroud)
问题
当我们的应用程序在韩国的客户PC上启动时,宽度约为20%.这意味着,右侧是一个只有灰色背景的区域.高度约为10%至高.这意味着,位于应用程序底部的项目位于屏幕之外.
修复
首先,我们认为问题来自Windows DPI设置.当我将笔记本电脑设置为125%时,它看起来很相似.但是,客户PC都设置为100%......
然后,我们考虑了屏幕分辨率.所有都有不同的,有些和我的笔记本电脑一样......
所有都有不同的grafic适配器......
都有.NET 4.5.1 ......
解决问题的唯一方法是一个奇怪的方法:
this.AutoScaleDimensions = …
Run Code Online (Sandbox Code Playgroud) 我遇到了让WinForms应用程序在高DPI设置下正确显示的问题.我检查了各种网站,WinForms都有正确的AutoScaleMode.我已经尝试将它设置为DPI和Font.但是,当使用高DPI设置(例如125%)时,表格总是会在底部附近被切断.
我添加了一些代码来检查,如果我将AutoScaleMode设置为DPI,当表单加载时,我看到表单加载时AutoScaleDimensions为120,120,而CurrentAutoScaleDimensions也为120,120.在Form.designer.cs文件中,有一行将AutoScaleDimension设置为96,96.
如果我将AutoScaleMode设置为Font,那么我可以在设计器中看到AutoScaleDimension被正确设置为新的System.Drawing.SizeF(6F,13F),但是当表单加载时,AutoScaleDimension和CurrentAutoScaleDimension都设置为8F,16F.
这个应用程序混合了一些WPF和WinForms,WPF屏幕首先出现.因此,基于混合WinForms和WPF应用程序中的.Net 3.5中的DPI Scaling,我尝试为应用程序设置TextFormattingMode,并为首先显示的WPF屏幕设置"显示",但它没有任何区别.
坦率地说,我不知道造成这种情况的原因.我想我可以通过在运行时检测DPI来添加代码来以编程方式调整大小,但我不应该这样做.AutoScaleMode(和相关的)属性应该使这相当自动化.那么我还应该检查哪些可能会导致这个问题呢?
我们有一个现有的Windows .net应用程序,它使用所有自定义控件.
由于我们只是支持默认的96 dpi分辨率,因此这些天很顺利.
现在我们需要我们的应用程序是dpi感知的.当我们去下一个时,事情就会变得混乱
更高分辨率120或144等
最常见的问题
位图缩放问题和
文字截止
在我的应用程序中使用这样的修复是徒劳的(因为所有使用的控件都是
定制,不是dpi感知).
在修改我的application.manifest以启用dpi-awareness标志并在主窗体和其他窗体上将AutoScaleMode设置为AutoScaleMode.Dpi之后尝试的事情使用AutoScaleMode作为继承
图形g = this.CreateGraphics(); int dpi = int.Parse(g.DpiX.ToString());
switch (dpi)
{
case 125:
this.Font = new Font(this.Font.FontFamily, this.Font.Size * 125.0f / (float)(g.DpiX));
Debug.WriteLine("<<---- Selected DPI Resolution :" + " 125 DPI ---->");
break;
... so on
Run Code Online (Sandbox Code Playgroud)
但所有这些似乎都不适合我的情况.
有谁知道/建议我更好地解决这个问题.
谢谢
VATSAG
问题描述:
我目前正在开发Visual Basic .NET应用程序.事实证明,我的应用程序无法在运行不同于"标准"的dpi设置的系统上正常显示(在Windows XP下为100%= 96dpi).
当我更改系统的dpi设置时,我的GUI看起来有点混乱,你可以在下面的截图中看到(因为这是一个扩展问题,屏幕截图上的文字是德语的;不好意思):
Windows XP,100%规模,96 dpi - >一切看起来像我期望的那样.
Windows XP,125%缩放比例,120 dpi - >窗口底部的按钮不再适合窗口内部.
我想要实现的目标:
如果显示比例设置为100%以外的任何值,我想在应用程序启动时立即向用户显示一个警告对话框.
题:
有没有可能读取系统的dpi值?如果是这样,那将是怎样的?似乎有一个DisplayProperties类和DisplayInformation类,但据我所知它只适用于Windows-Store-Apps.
当我在Windows中在视网膜MacBook Pro上的VM中运行我的WinForm应用程序时,表单的大小在运行时缩小,而按钮同时向外移动.这可能导致底部边缘的按钮滑到窗口边缘下方,看不见.由于它们是底部锚定的,因此它们完全无法访问.从Windows原生桌面运行时,该应用程序通常表现良好.
只有表单上的字体或DPI AutoScaleMode
设置才会出现这种情况.使用Inherit或None,表单及其内容很大,但与我设计它们的方式成正比.
我用一个来自模板的新模板WinForm应用程序重现了这一点,除了调整表单大小,只需按一下按钮就可以了.如何在不相对于彼此改变尺寸的情况下扩展应用程序?
这是InitializeComponent()
方法designer.cs
:
private void InitializeComponent()
{
this.sendButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// sendButton
//
this.sendButton.Location = new System.Drawing.Point(60, 856);
this.sendButton.Margin = new System.Windows.Forms.Padding(4);
this.sendButton.MinimumSize = new System.Drawing.Size(200, 60);
this.sendButton.Name = "sendButton";
this.sendButton.Size = new System.Drawing.Size(200, 62);
this.sendButton.TabIndex = 1004;
this.sendButton.Text = "Send";
this.sendButton.UseVisualStyleBackColor = true;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(282, 981);
this.Controls.Add(this.sendButton); …
Run Code Online (Sandbox Code Playgroud)