WPF 高 dpi 问题
我创建了一个简单的 Web 浏览器 WPF 测试应用程序,在画布中包含图片和文本,窗口设置为 96dpi。
然后我切换到 120 dpi 和:-((( 显示很乱,图像大小发生了变化,部分画布看不见了...
当我使用 Winforms 时,我将 AutoScaleMode 属性设置为 None 并且窗口保持其大小,控件也是如此,继承字体的控件可以正确显示,不模糊,也不太大...
我可以做什么来模仿 W-F 中的这种(良好)行为?
I created a simple web browser WPF test application with pictures and text within a canvas, with windows set at 96dpi.
Then I switched to 120 dpi and :-((( Display is messy, image size changed and part of the canvas is out of view...
When I used Winforms, I set the AutoScaleMode property to None and the windows keeps its size, the controls as well, the controls which have inherited font are properly displayed, not blurry and not too big...
What can I do to mimic this (good) behavior in W¨F?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不清楚“Web 浏览器 WPF ...应用程序”是什么意思。 WPF 不在 Web 浏览器中运行,除非您谈论的是 XBAP。或者你在做Silverlight?或者它只是一个 WPF 导航应用程序,根本不基于浏览器?你需要澄清一下。
当您在高 DPI 模式下运行时,WPF 会自动缩放您的内容。这是预期的行为:如果用户明确表示他们希望屏幕上的所有内容都更大,那么 WPF 将尊重用户的意愿。旧的 WinForms 黑客“假装高 DPI 不存在,只是以正常的小尺寸显示所有内容,并希望它不会让用户太生气”在 WPF 中不可用;如果你努力的话,你可能会效仿他们,但你会被强烈引导去做正确的事。
WPF 缩放一切,因此您的“画布的一部分在视图之外”的说法没有意义。它应该将画布、其父窗口及其子元素缩放相同的量,因此如果所有内容都适合 96dpi,那么它也应该适合 120dpi 和 144dpi。如果没有,那么您正在做一些奇怪的事情,并且您必须提供重现该问题的代码示例。
您似乎声称在高 DPI 模式下运行时字体模糊,这听起来很奇怪。字体呈现为矢量,因此它们应该清晰地缩放,并且即使在高 DPI 模式下也能清晰地呈现。我从未见过你描述的模糊字体,所以再次,你必须提供一个重现案例。
我唯一希望模糊的是图像。如果您在 UI 中使用光栅(位图)图像(BMP / GIF / JPG / PNG)——例如,工具栏上的图标——那么,是的,当它们缩放时,它们看起来会很糟糕。当您使用小位图并将其放大时,它看起来总是很糟糕。您可以尝试通过使用较大的图像并缩小它们的显示大小来解决此问题 - 例如,如果您希望工具栏图像为 16x16(在标准 96 dpi 模式下),那么您可以尝试在您的工具栏中放置一个 32x32 位图。项目,在 XAML 中设置 Image 元素的 Width="16" 和 Height="16",并查看是否看起来更好。它实际上在 120dpi 模式下为 20x20 物理像素,在 144dpi 模式下为 24x24,这两个像素仍将从 32x32 资源中按比例缩小,因此比必须放大的 16x16 源图像具有更好的外观。 (不过,我还没有在 WPF 工具栏中尝试过这种技术,所以我不知道它在实践中对典型工具栏图像的实际效果如何。)
解决缩放图像问题的最佳方法是使用矢量图像而不是光栅图像。不幸的是,很难找到矢量图像库。它们数量很少,相距很远,通常不如位图图像全面,而且通常很昂贵。
I'm not clear on what you mean by "web browser WPF ... application". WPF doesn't run in a Web browser, unless you're talking about an XBAP. Or are you doing Silverlight? Or is it just a WPF navigation application and not browser-based at all? You'll need to clarify.
WPF automatically scales your content when you run in high-DPI modes. This is intended behavior: if the user explicitly says they want everything to be bigger on the screen, then WPF will respect the user's wishes. The old WinForms hacks of "pretend high-DPI doesn't exist, just show everything at the normal small size and hope it doesn't piss the user off too much" aren't available in WPF; you could probably emulate them if you worked at it, but you're steered very strongly toward doing the Right Thing.
WPF scales everything, so your statement that "part of the canvas is out of view" doesn't make sense. It should be scaling the canvas, its parent window, and its child elements all by the same amount, so if everything fits at 96dpi, it should also fit at 120dpi and 144dpi. If not, then you're doing something strange and you'll have to provide a code sample that reproduces the problem.
You seem to be claiming that fonts are blurry when you run in a high-DPI mode, which sounds very strange. Fonts are rendered as vectors, so they should scale cleanly, and render crisply even in high-DPI modes. I've never seen the blurry fonts you describe, so again, you'll have to provide a repro case.
The only thing that I would expect to be blurry are images. If you're using raster (bitmap) images (BMP / GIF / JPG / PNG) in your UI -- for example, for the icons on a toolbar -- then yes, those will look pretty bad when they're scaled. It pretty much always looks bad when you take a small bitmap and make it larger. You might try working around this by using larger images and sizing them down for display -- for example, if you want your toolbar images to be 16x16 (when in standard 96-dpi mode), then you could try putting a 32x32 bitmap in your project, setting the Image element's Width="16" and Height="16" in your XAML, and seeing if that looks any better. It would actually be 20x20 physical pixels in 120dpi mode, and 24x24 in 144dpi mode, both of which would still be scaled down from the 32x32 resource and would therefore have a better shot of looking good than a 16x16 source image that's had to be scaled up. (I haven't tried this technique in a WPF toolbar, though, so I don't know how well it would really work in practice with typical toolbar images.)
The very best way to get around the problems with scaling images would be to use vector images instead of raster. Unfortunately, it's hard to find libraries of vector images. They're few, far between, typically less comprehensive than what you can find for bitmap images, and often expensive.
大概您使用固定长度单位 (px)。尝试重新布局您的项目,同时牢记 WPF 布局规则。 此页面提供了一些最佳实践。
Presumably you use fixed length units (px). Try re-layouting your project keeping the WPF layout rules in mind. This page has some best practices for that.
我刚刚在 .NET 4 中的 WPF 下发现了一个使用
MaxHeight
的错误,该错误设置在由另一个 Style 继承的 Style 中,并用作StaticResource
,但没有受到用户设置的 DPI 的影响。我将它从MaxHeight
设置为Height
,然后它受到了 DPI 的影响。我怀疑这里的 .NET 4(可能还有其他框架)存在错误。I just found a bug using
MaxHeight
under WPF in .NET 4, set in a Style that gets inherited by another Style and that is used as aStaticResource
, which didn't get influenced by the DPI set by the user. I set it fromMaxHeight
toHeight
, then it got influenced by the DPI. I suspect a bug in the .NET 4 (and possibly other frameworks) here.