MaterialDesignInXAML / MaterialDesignInXamlToolkit

Google's Material Design in XAML & WPF, for C# & VB.Net.
http://materialdesigninxaml.net
MIT License
14.82k stars 3.4k forks source link

Blurry `ToggleButton` #3612

Closed MichelMichels closed 4 days ago

MichelMichels commented 1 week ago

Following line makes the ToggleButton thumb blurry (the circle that switches side when toggling the button.

<AdornerDecorator CacheMode="{Binding RelativeSource={RelativeSource Self}, Path=(wpf:ShadowAssist.CacheMode)}">

Link to line in source code

This binding on CacheMode seems at first hand also completely unnecessary, as this value can't be set in any way:

The value will always be the default value of ShadowAssist.CacheMode, which seems to be following value new BitmapCache { EnableClearType = true, SnapsToDevicePixels = true }.

When I remove the CacheMode setting, the circle renders crisp and sharp.

With CacheMode set Without CacheMode set
image image
nicolaihenriksen commented 1 week ago

@MichelMichels Probably related to changes for this and prior issue mentioned in there #3568.

The CacheMode can actually be set, because the attached property is inheritable and thus could be set/cleared on the ToggleButton which would affect the adorner.

Probably worth visiting to see if the recent changes from explicit CacheMode to the AP binding has other similar side-effects (other controls) we just haven't caught.

MichelMichels commented 1 week ago

ofcourse, I forgot about inheritable properties. I knew I missed something. What would be the most appropriate way to fix this?

nicolaihenriksen commented 1 week ago

@MichelMichels I am not really sure actually. I would like to hear @Keboo opinion on the matter...

MichelMichels commented 6 days ago

@nicolaihenriksen I made a test repository with the Nuget packages to check whether the ShadowAssist.Cachemode is inherited, and this does not seem to be the case. Did I do something wrong? https://github.com/MichelMichels/MDIXTestApp/tree/togglebutton-cachemode-bug

MichelMichels commented 6 days ago

@nicolaihenriksen, so I revisited my test app and added a case where I set ShadowAssist.CacheMode equal to {x:Null}. This seems to clear the blurryness, and indeed gets inherited!

image

This is run with latest Nuget packages (5.1.0) on a Windows 11 machine.

MichelMichels commented 6 days ago

Also, when increasing the RenderAtScale from 1 to 3, the bluryness also dissappears while (I guess) still retaining the caching ability. Documentation found at https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.bitmapcache?view=windowsdesktop-8.0

nicolaihenriksen commented 6 days ago

@MichelMichels yes I just ran your sample app, and was confused why you did not think it was inheriting 😄

I think the confusion perhaps comes from the fact that the attached property has a default value which makes things blurry 😢 Looking that the doc link you posted, perhaps the default value should be changed to something more appropriate where RenderAtScale is increased?

MichelMichels commented 6 days ago

@nicolaihenriksen yes, I think maybe a default setting of 2 or 3 should be better. The test was run on a monitor with resolution 1920x1200. Which seems to me a common resolution. Maybe we could try to write a test to measure the rendering time increase for these values? I must say I'm not that familiar with testing should cases.

nicolaihenriksen commented 6 days ago

@MichelMichels I must also admit that my knowledge of BitmapCache in general, and more so, testing of rendering performance in that regards, is not something I am familiar with either. I think your suggestion seems viable, perhaps make a PR with the change, point out in the description why you're making this change and that you think maybe some level of testing is needed. Perhaps @Keboo is more experienced in this area than us, and can provide some valuable input.

MichelMichels commented 6 days ago

Perfect, I'll submit a PR tonight (CET 1900 or later)

MichelMichels commented 5 days ago

@nicolaihenriksen RenderAtScale with higher value than 1 seems to create jagged edges for controls when they are small (like the default width of a ToggleButton). So in my PR I choose to remove the preset value altogether by setting it to null.