-1

When a user changes the system dpi (in Settings -> Display) a WPF Window becomes blurry. Closing the application and restarting it makes it clear again.

How can I get the Window clear again without closing it?

Recreate by creating a WPF app, adding a button and running it. Then change the dpi as mentioned above. Even changing it back again doesn't help.

ispiro
  • 26,556
  • 38
  • 136
  • 291
  • happens for every wpf application(even newly created ones)? – Lei Yang Jul 14 '21 at 12:58
  • @LeiYang Yes. Just create one, put a button on it, and change the system dpi. You'll see the text on the button become blurry. – ispiro Jul 14 '21 at 12:59
  • i'm not very familiar with dpi. is there such setting? is it equal to the 'resolution(1920*1080)' list? – Lei Yang Jul 14 '21 at 13:00
  • As a workaround you can monitor for DPI change and force UI reloading. See [this topic](https://stackoverflow.com/q/64355684/1997232). – Sinatr Jul 14 '21 at 13:05
  • @Sinatr DpiChanged doesn't fire. Try it and see for yourself. Also, how would I be able to reload the UI - do you mean remove all elements from the Window and put them back there? Because if so, it doesn't work - the button returns blurry. – ispiro Jul 14 '21 at 13:10
  • 1
    To reload UI try to close window and open it again. You need to customize [entry point](https://stackoverflow.com/q/6156550/1997232). If reloading UI is not enough, then just do [restart](https://stackoverflow.com/q/4773632/1997232). User don't change DPI often, right? – Sinatr Jul 14 '21 at 13:15
  • @Sinatr `User don't change DPI often, right?` - _Some_ user is going to... I was hoping there would be some method I can call to "reload" the dpi. – ispiro Jul 14 '21 at 13:41
  • Have you tried registering to SystemEvents.DisplaySettingsChanged in your MainWindow.xaml.cs, and then calling `this.UpdateLayout()`? – Tam Bui Jul 14 '21 at 16:08
  • @TamBui `UpdateLayout` doesn't help. Tested. – ispiro Jul 14 '21 at 16:29
  • @Sinatr I have a PC with displays with different DPIs, whenever I drag a window from one screen to another that counts as a _DPI change_ as far as the application is concerned. That said, **just enable per-monitor DPI awareness** and WPF should handle it fine. – Dai Aug 02 '21 at 20:48
  • 1
    @Dai, I expect wpf applications to be dpi aware [by defaut](https://stackoverflow.com/q/35865238/1997232). But it seems to be not ideal. Perhaps OP should post [mcve] so that you can reproduce the issue and try to find a better solution. I just suggest a workaround - to restart, that should help if everything was ok before DPI change. – Sinatr Aug 03 '21 at 07:06
  • @Sinatr I’m guessing the OP’s project is an older WPF app running against something older than .NET Fx 4.7.2 and so per-monitor DPI awareness is disabled for back-compact purposes. The OP needs to test a _brand new_ blank WPF project targeting .NET Fx 4.8 or .NET 5. – Dai Aug 03 '21 at 07:10
  • @Sinatr `minimal reproducible example` - I'm pretty sure anyone who's capable of answering this question is also capable of creating a WPF application and adding a button to it. – ispiro Aug 03 '21 at 07:11
  • @Dai No. It's a the latest .net 4.8 with the latest Visual Studio version. With a brand new WPF project. Try it and see. – ispiro Aug 03 '21 at 07:12
  • @ispiro “ I'm pretty sure anyone who's capable of answering this question is also capable of creating a WPF application and adding a button to it” - yes, and per-monitor DPI awareness works correctly for me. Something is wrong or broken with your computer. – Dai Aug 03 '21 at 07:13
  • @Dai But your suggestion for per-monitor dpi awareness did work. Which I find strange since I'm only working on one monitor. Anyway, you can post that as an answer, because strange or not - it works. – ispiro Aug 03 '21 at 07:13
  • @Dai See my previous comment. Per-monitor DPI awareness does, in fact, work. Thanks! – ispiro Aug 03 '21 at 07:14
  • @ispiro How, **exactly** did you enable per-monitor DPI awareness? – Dai Aug 03 '21 at 07:14
  • @Dai I said it _did_ work. Not that it didn't. And I used `PerMonitor`. – ispiro Aug 03 '21 at 07:15
  • @ispiro You shouldn’t need to do that though. Unless, did your project already have a custom app.manifest? – Dai Aug 03 '21 at 07:16
  • @Dai As I've said above, this is a completely new WPF project. VS -> New project -> etc. so yes, I needed to add an app.manifest file to it. And if you think per-monitor-etc. is by default - [you're not alone. And you are backed by a Microsoft blog post.](https://stackoverflow.com/a/39218709/939213) But unfortunately [still wrong](https://stackoverflow.com/questions/39217355/wpf-application-blurry-on-high-dpi-screen-on-windows-10#comment85923370_39218709). – ispiro Aug 03 '21 at 07:20
  • @Dai Please feel free to post your answer. My answer is just there in case you don't. – ispiro Aug 03 '21 at 07:24
  • @Dai Also, instead of me posting an answer myself, please feel free to post an answer to [my bountied question here](https://stackoverflow.com/q/68379924/939213) since you're the one who deserves that bounty. – ispiro Aug 03 '21 at 07:43
  • @ispiro I really don't need +50 reputation :) – Dai Aug 04 '21 at 02:44

1 Answers1

1

As Dai pointed out, adding per-monitor dpi-awareness fixes the issue.

Why, I'm not sure, since that's not supposed to affect a device using one monitor. But it works.

Since it seems that many think that per-monitor dpi-awareness is on by default, let me point out, as pointed out by Ben Voit, that it's not.

ispiro
  • 26,556
  • 38
  • 136
  • 291