在这篇文章中,CodeNaked讨论了如何更改应用程序的TextFormattingModeProperty.这完全解决了我的问题(见下文).Net 4.然而我的生产应用程序是在.Net 3.5中,根本没有该属性.我如何在.Net 3.5中完成同样的事情?
我的根本问题:
我有一个基于.Net 3.5的winforms应用程序,在某些屏幕上有一些WPF控件.当Windows DPI设置设置为150%(而不是120%)时,会按预期进行缩放.但是,只要创建了WPF控件,所有窗口的缩放比例都会设置为100%.我希望缩放保持不变.
我创建了一个测试应用程序来演示.默认情况下,它会打开一个winform,其中包含一个按钮,该按钮将使用wpf控件打开另一个winform.保持不变,打开第二个表单将导致缩放恢复到100%.但是,如果取消注释Form1.vb中的第11行,则在打开第二个表单时将继续正确进行缩放.
Dim newApp As New App() 'Uncomment to fix automatic scaling
Run Code Online (Sandbox Code Playgroud)
班级应用:
Imports System.Windows
Imports System.Windows.Media
Partial Public Class App
Inherits Application
Public Sub App()
TextOptions.TextFormattingModeProperty.OverrideMetadata(GetType(Window), New FrameworkPropertyMetadata(TextFormattingMode.Display, FrameworkPropertyMetadataOptions.AffectsMeasure Or FrameworkPropertyMetadataOptions.AffectsRender Or FrameworkPropertyMetadataOptions.Inherits))
End Sub
End Class
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(和相关的)属性应该使这相当自动化.那么我还应该检查哪些可能会导致这个问题呢?
首先,我想提出一些问题的背景:我们有大型的遗留WinForms应用程序,我们决定转向WPF.但是从头开始完全重写应用程序是不可能的(包括业务在内的很多原因),我们将逐步完成这种迁移(一种接一种形式).所以现在我们需要在WinForms应用程序中使用WPF窗口和控件.
今天我在迁移过程中迈出了第一步:我在WPF上重新创建了一些简单的表单(它变成了一个Window).我刚刚在WPF上重新创建的新窗口是通过按下其他窗体上的按钮打开的(这是标准的WindowsForms格式). 重要提示:我的Windows设置为120 DPI,而不是默认96.所有的事情都很好,直到我启动应用程序看看是什么新窗口.
所以,这就是我所看到的:App正常启动,并且一如既往地看着.我打开"父"窗体并按下按钮打开新的WPF窗口.按下按钮WPF窗口按预期打开后,但所有可见的应用程序元素(主窗口,"父"窗体,按钮,工具栏等),包括新的WPF窗口,增加了它们的大小,它们开始变得更大.并非全部.当我关闭WPF窗口时,没有任何规模发生 - 所有应用程序元素仍然很大.然后我关闭了"父"表单,从中我打开了WPF窗口.这就是魔术 - 所有应用程序元素都重新调整为原始大小.然后我再次打开"父"窗体和WPF窗口 - 但是缩放没有改变,所有应用程序元素都保持了它们的大小.我多次重复"打开 - 关闭""父"窗体和WPF窗口(在相同的应用程序运行期间,我没有重新启动应用程序) - 没有调整元素的大小.
在此之后,我进行了一些调查,并得出了这样的结论:如果我在主应用程序初始化之前在Program.cs文件中放置任何代码,使用WPF程序集中的任何类型,那么应用程序将始终绘制比它们更大的所有元素之前,但在打开WPF窗口时,不会有任何比例变化.Program.cs文件的示例(在我的例子中称为EntryPoint):
internal sealed class EntryPoint
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
try
{
Application.SetCompatibleTextRenderingDefault(false);
Application.EnableVisualStyles();
****System.Windows.Application wpfApp = new System.Windows.Application();****
App.Start(args);
if(App.Context != null)
App.Show();
}
catch(Exception ex)
{
App.ShowError(Properties.Resources.UnexpectedError, ex);
Application.Exit();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我添加了标有****的行(对不起,无法弄清楚如何在代码段中使行变粗).在我理解的几个测试中,我添加的代码并不重要 - 它可以创建新的System.Windows.Window对象,即使没有显示它,也可以使用WPF程序集中任何类型的任何其他代码行.
所以,主要的问题是:什么可能导致描述的行为?如果有人遇到这个问题,或者有任何想法,如果你分享你的想法,它会很棒.
感谢您阅读这个不那么简短的问题.