禁用 WPF 应用程序的 DPI 感知 [英] Disable DPI awareness for WPF application

查看:32
本文介绍了禁用 WPF 应用程序的 DPI 感知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

美好的一天!

我一直在开发 WPF 应用程序一段时间(作为一种学习体验,哦,天哪,这是一种学习体验),它终于准备好发布了.发布意味着将它安装在我的 HTPC 上,用于浏览我的电影收藏.

我在我的 PC 上设计它,它运行 1920*1080 但在正常 DPI 设置下,而 HTPC/TV 运行在相同的分辨率下,但出于显而易见的原因,DPI 设置更高.

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

[程序集:System.Windows.Media.DisableDpiAwareness]

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

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

谢谢,约翰

解决方案

DPIAwareness

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

你在 XP 上运行吗?该选项可能不适用于该平台.

您可以调用 IsProcessDPIAware 来检查您的应用进程是否已应用该设置.

找出 DPI

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

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

双dpiX,双dpiY;PresentationSourcepresentationsource = PresentationSource.FromVisual(mywindow);if (presentationsource != null)//确保它已连接{dpiX = 96.0 *presentationsource.CompositionTarget.TransformToDevice.M11;dpiY = 96.0 *presentationsource.CompositionTarget.TransformToDevice.M22;}

进行缩放调整

  • 使用 ViewBox 技巧

    请参阅我之前制作的这个答案,它允许 Canvas 使用被解释为本机"的位置像素,无论 DPI 缩放如何.

    用于 LCD 屏幕全高清的 WPF

  • 访问 CompositionTarget 上的 TransFormToDevice 缩放矩阵,并从中计算出一个新矩阵,该矩阵只是撤消缩放并在 LayoutTransformRenderTransform.

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

Good day!

I've been working on a WPF app for some time now (as a learning experience and oh boy it was a learning experience) and it's finally ready for release. Release means installing it on my HTPC where it will be used to browse my movie collection.

I designed it on my PC which runs 1920*1080 but at the normal DPI setting, while the HTPC/TV is running at the same resolution but a higher DPI setting for obvious reasons.

The problem is my app goes bonkers on the HTPC, messing up pretty much everything as far as visuals go. I know this is due to bad design (mea culpa), but since it's an application that will only be used by me I'm looking for an quick fix, not a full redesign. I read it would be possible to stop the app from being DPI aware by adding the following to AssemblyInfo.cs:

[assembly: System.Windows.Media.DisableDpiAwareness]

However, it doesn't seem to have any effect and the behavior of the app remains the same.

Could anyone point me in the right direction?

Thank you, Johan

解决方案

DPIAwareness

Just some ideas (not tried):

Are you running on XP? That option might not work on that platform.

What follows are probably just different ways to set the same DpiAwareness option:

  • look at the "compatibility mode" settings on your EXE...right click it's properties...and turn on "Disable display scaling"

  • create a manifest, and say you aren't aware

    <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>
    

  • call SetProcessDPIAware (think you have to call this early i.e. before Window is created)

    http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633543(v=vs.85).aspx

You can call IsProcessDPIAware to check if your apps process has had the setting applied to it or not.

Finding out the DPI

Here's how you find out what DPI you are currently using:

Access CompositionTarget via the PresentationSource of your Window to find out what DPI scaling it's using.....you can then use the values to do some scaling adjustments i.e. scale down your "stuff" (whose sizes/length/etc are specified in Device Independent Units), so that when its scaled up due to a higher DPI being in effect it doesn't explode the physical pixel usage (...this can be done in various ways e.g. ViewBox, or calculations on widths, etc on elements ).

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;
}

Do Scaling Adjustments

  • use the ViewBox trick

    See this answer I made before that allowed a Canvas to use positions that were interpreted as "native" pixel no matter what the DPI scaling.

    WPF for LCD screen Full HD

  • access the TransFormToDevice scaling matrix on the CompositionTarget, and from that calculate a new matrix that just undoes that scaling and use that in LayoutTransform or RenderTransform.

  • use a method (maybe even put it in a Converter) that modifies a DIP (Device Independent Position) position/length on an explicit basis....you might do that if you want your Window Size to match a particular pixel size.

这篇关于禁用 WPF 应用程序的 DPI 感知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆