WPF/Accessibility: Setting FontSize property prevents system font scaling from working
Environment:
- .NET Core 3.1
Problem description:
While doing an accessibility pass for FancyZones Editor in PowerToys, we've encountered this issue. I've given a detailed explanation in this comment, but it boils down to the difference between FontSize property behavior in UWP/WPF.
Actual behavior:
Setting FontSize property in WPF prevents system-wide font scaling setting from working, no matter which context switch overrides are enabled.
Expected behavior:
Same as with UWP apps: elements' font size changes depending on the scale setting even when FontSize is explicitly set for them.
Minimal repro:
- create Blank WPF app
- go to
MainWindow.xamland add the following xaml inside theGrid:
<TextBlock Text="THE TEXT" FontSize="24"/>
- launch the application
- Start ->"Make text size bigger" -> Change to e.g. 200%
- Observe that the text size remains the same
Now repeat the steps with a blank UWP app and observe that "Make text size bigger" option affects text size.
@yuyoyuppe "em" units are not supported as of now by WPF. For PowerToys, you can get the issue resolved by using the Markup-extension, as described here: https://stackoverflow.com/questions/653918/wpf-analogy-for-em-unit
I was wondering if this has had any movement?
Adding the following code to WinUI3
<Button x:Name="myButton" Click="myButton_Click" FontSize="12">Click Me</Button>
Appears to honor font scaling. Yet if I were to do the same with WPF the font would not scale.
It appears 3701 has the same problem but offers a different solution.
I'm also really struggling with creating WPF UI that can pass WCAG accessibility wrt text scaling. The only way to do it is to not ever set font-size, since the default text style does seem to react to scaling. I can't for the life of me figure out how that actually works in WPF, but the moment you assign a font size that feature is gone, so you can't for instance make headers that are larger than the normal text and scales with the text.
I can't for the life of me figure out how that actually works
System.Windows.SystemResources creates a hidden window that listens for WM_SETTINGCHANGE message in SystemThemeFilterMessage hook. That effectively calls SystemResources.InvalidateTreeResources which coerces bunch of properties including FontSize. The coerce method for FontSize is FrameworkElement.CoerceFontSize which returns the SystemFonts.MessageFontSize. If nothing has set the FontSize value explicitly, this default propagates to the tree like any other DP.