禁用WPF应用程序的DPI感知

Joh*_*len 26 wpf scaling dpi

美好的一天!

我已经在WPF应用程序上工作了一段时间(作为一种学习经验,哦,这是一次学习经历),它终于准备发布了.发布意味着将其安装在我的HTPC上,用于浏览我的电影收藏.

我在我的PC上设计了它,它运行1920*1080,但是在正常的DPI设置下,而HTPC/TV以相同的分辨率运行但DPI设置更高,原因很明显.

问题是我的应用程序在HTPC上疯狂,就视觉效果而言几乎搞乱了一切.我知道这是由于糟糕的设计(mea culpa),但由于它是一个仅供我使用的应用程序,我正在寻找快速修复,而不是完全重新设计.我读过可以通过将以下内容添加到AssemblyInfo.cs来阻止应用程序识别DPI:

[assembly: System.Windows.Media.DisableDpiAwareness]
Run Code Online (Sandbox Code Playgroud)

但是,它似乎没有任何影响,应用程序的行为保持不变.

有人能指出我正确的方向吗?

谢谢你,约翰

Col*_*ith 34

DPIAwareness

只是一些想法(未尝试):

你在XP上运行吗?该选项可能无法在该平台上运行.

以下内容可能只是设置相同DpiAwareness选项的不同方法:

  • 查看EXE上的"兼容模式"设置...右键单击它的属性...并打开"禁用显示缩放"

  • 创建一个清单,并说你不知道

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
     ...
      <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
          <dpiAware>false</dpiAware>
        </asmv3:windowsSettings>
      </asmv3:application>
     ...
    </assembly>
    
    Run Code Online (Sandbox Code Playgroud)
  • 调用SetProcessDPIAware(想想你必须尽早调用它,即在创建Window之前)http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633543( v=vs.85)

    .aspx

您可以致电IsProcessDPIAware查看您的应用流程是否已应用该设置.

找出DPI

以下是您了解目前使用的DPI的方法:

CompositionTarget通过PresentationSource你的访问Window来找出它使用的DPI缩放.....你可以使用这些值进行一些缩放调整,即缩小你的"东西"(其大小/长度/等在设备独立单元中指定)因此,当它由于更高的DPI实际放大时,它不会爆炸物理像素的使用(......这可以通过各种方式完成,例如ViewBox,或者对元素的宽度等进行计算).

double dpiX, double dpiY;
PresentationSource presentationsource = PresentationSource.FromVisual(mywindow);

if (presentationsource != null) // make sure it's connected
{
    dpiX = 96.0 * presentationsource.CompositionTarget.TransformToDevice.M11;
    dpiY = 96.0 * presentationsource.CompositionTarget.TransformToDevice.M22;
}
Run Code Online (Sandbox Code Playgroud)

缩放调整

  • 使用ViewBox技巧

    看到我之前做的这个答案允许Canvas使用被解释为"原生"像素的位置,无论DPI缩放是什么.

    WPF用于液晶屏全高清

  • 访问该TransFormToDevice缩放矩阵CompositionTarget,并从中计算出一个新的矩阵,该矩阵只是撤消该缩放并在LayoutTransform或中使用该矩阵RenderTransform.

  • 使用一种方法(可能甚至把它放在一个转换器中)明确修改DIP(设备独立位置)位置/长度......如果你希望你的窗口大小匹配特定的像素大小,你可以这样做.


ula*_*ekh 6

这篇博客文章解释了如何使用Decorator子类来做到这一点.

简而言之,创建一个这样的类:

namespace MyNamespace
{
    public class DpiDecorator : Decorator
    {
        public DpiDecorator()
        {
            this.Loaded += (s, e) =>
            {
                Matrix m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
                ScaleTransform dpiTransform = new ScaleTransform(1 / m.M11, 1 / m.M22);
                if (dpiTransform.CanFreeze)
                    dpiTransform.Freeze();
                this.LayoutTransform = dpiTransform;
            };
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

然后加入像xmlns:custom="clr-namespace:MyNamespace"你的顶层窗口定义,然后附上您DPI独立的用户界面<custom:DpiDecorator>... </custom:DpiDecorator>.