以上方法均无法真正禁用WPF的dpi缩放。
.Net 4.6中WPF计算dpi缩放的方法如下:
1)HwndTarget是所有可视元素使用的CompositionTarget。
2)UIElement是可视元素的基类,也是dpi缩放计算结果存储的地方。
WPF确保全局缩放在准备第一个可视元素时计算一次。这由HwndTarget上的布尔值控制{private static bool _setDpi = true}。计算dpi后,将_setDpi字段设置为false,并使用此代码快捷方式使用dpi感知方法{if(!HwndTarget._setDpi) return;}。
每个UIElement都有相似的东西,它具有使用{private static bool _setDpi = true}的相同模式,以允许首次计算。
接下来的检查来自ProcessDpiAwareness,它可以是None、Process或Monitor。为了阻止WPF考虑单个监视器,您需要将ProcessDpiAwareness设置为Process(int 1)。
最后,当计算dpi时,结果存储在名为DpiScaleXValues和DpiScaleYValues的2个列表中。因此,您需要初始化这些正确的值。
以下是我自己使用的示例代码(仅适用于.net 4.6):
var setDpiHwnd = typeof(HwndTarget).GetField("_setDpi", BindingFlags.Static | BindingFlags.NonPublic);
setDpiHwnd?.SetValue(null, false);
var setProcessDpiAwareness = typeof(HwndTarget).GetProperty("ProcessDpiAwareness", BindingFlags.Static | BindingFlags.NonPublic);
setProcessDpiAwareness?.SetValue(null, 1, null);
var setDpi = typeof(UIElement).GetField("_setDpi", BindingFlags.Static | BindingFlags.NonPublic);
setDpi?.SetValue(null, false);
var setDpiXValues = (List<double>)typeof(UIElement).GetField("DpiScaleXValues", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null);
setDpiXValues?.Insert(0, 1);
var setDpiYValues = (List<double>)typeof(UIElement).GetField("DpiScaleYValues", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null);
setDpiYValues?.Insert(0, 1);