This post describes the new WPF and accessibility features and improvements in .NET Framework 4.7.1. You can try out these features by downloading the Developer Pack, described in the Welcome to the .NET Framework 4.7.1 Early Access blog post.
Accessibility improvements
.NET Framework 4.7.1 brings in a lot of accessibility improvements across different libraries to align with the broad Microsoft product accessibility goals.
How to get these accessibility improvements?
In order for the application to benefit from these changes, it needs to run on the .NET Framework 4.7.1 or later and configured in one of the following ways:
- It is recompiled to target the .NET Framework 4.7.1. OR
- It opts out of the legacy accessibility behaviors by adding the following AppContext Switch to the <runtime> section of the app config file and setting it to false, as the following example shows.
Applications that target the .NET Framework 4.7.1 or later and want to preserve the legacy accessibility behavior can opt in to the use of legacy accessibility features by explicitly setting this AppContext switch to “true”.
WPF Accessibility improvements
Accessibility improvements in WPF are in the following areas:
- UIAutomation LiveRegion support
- Screen Readers
- High Contrast
UIAutomation LiveRegion Support
Screen readers such as Narrator help people read the UI contents of an application, usually by text-to-speech output of the UI content that’s currently focused. However, if a UI element changes somewhere in the screen and it is not being focused at that point in time, the user may not be notified, and so they may be missing important information.
LiveRegions are meant to solve this problem. A developer can use them to inform the screen reader, or any other UIAutomation client, that an important change has been made to a UI element. The screen reader can then make decisions of its own as to how and when to inform the user of this change. The LiveSetting property also informs the screen reader of the importance of the UI change to the user.
LiveSettingProperty and LiveRegionChangedEvent have been added to System.Windows.Automation.AutomationElementIdentifiers, settable via XAML.
A new DependencyProperty is now registered for “LiveSetting” under System.Windows.Automation.AutomationProperties, as well as Set and Get methods. System.Windows.Automation.Peers.AutomationPeer now has a new method GetLiveSettingCore, which can be overridden to provide a LiveSetting value.
A new enumeration for the possible values of LiveSetting has been added to System.Windows.Automation.
How to make a LiveRegion?
You can set the AutomationProperties.LiveSetting property on the element of interest to make it a “LiveRegion” as shown in the following sample.
Announcing an important UI change
When the data changes on your LiveRegion, and you feel the need to inform a screen reader about that change, you need to explicitly raise an event as illustrated by the following sample.
Screen reader
You can observe the following accessibility improvements in the screen reader area after you opt-in to the Accessibility improvements in .NET Framework 4.7.1.
- In previous versions, Expanders were announced by screen readers as buttons, they are now correctly announced as groups (expand/collapse).
- In previous releases, DataGridCells were announced by screen readers as “custom”, they are now correctly announced as data grid cell (localized).
- Now Screen readers will announce the name of an editable ComboBox.
- In previous releases, PasswordBoxes were announced as “no item in view” or had otherwise incorrect behavior, this issue is now fixed.
High Contrast
There are High Contrast improvements in various WPF controls and they are visible when High Contrast theme is set.
Expander control
The focus visual for the expander control is now visible. The keyboard visuals for combo-box, list-box and radio buttons are visible as well.
Before:
After:
CheckBox and RadioButton
The text in CheckBox and RadioButton is now easier to see when selected in high contrast themes.
Before:
After:
ComboBox
The border of a disabled ComboBox is now the same color as disabled text.
Before:
After:
Disabled and focused buttons use the correct theme color.
Before:
After:
Setting a ComboBox’s style to Toolbar, ComboBoxStyleKey caused the dropdown arrow to be invisible, this issue is now fixed.
Before:
After:
DataGrid
The sort indicator arrow in DataGrid now uses correct theme colors.
Before:
After:
Previously, default link style changed to incorrect color on mouse over in high contrast modes and this is now resolved. Similarly, DataGrid checkbox column now uses the expected colors for keyboard focus feedback.
Before:
After:
Windows Forms Accessibility improvements
Windows Forms accessibility changes are in the following areas. We will talk about these in detail in an upcoming blog post.
- Improved display during High Contrast mode
- Improved property browser experience
- Enhanced UI accessibility patterns
WPF – Changing implicit data templates
This feature enables the automatic update of elements that use implicit DataTemplates after changing a resource. When an application adds, removes, or replaces a value declared in a ResourceDictionary, WPF automatically updates all elements that use the value in most cases, including the implicit style case: <Style TargetType=”Button”. Here the value should apply to all buttons in the scope of the resource. This feature supports a similar update in the implicit data template case where the value should apply to all in-scope ContentPresenters whose content is a Book: <DataTemplate DataType=”{x:Type local:Book}”>
This feature’s principal client is Visual Studio’s “Edit-and-Continue” facility, when a user changes a DataTemplate resource in a running application and expects to see the effect of that change when the application continues. However it could also prove useful to any application with changing DataTemplate resources.
The feature is controlled by a new property ResourceDictionary.InvalidatesImplicitDataTemplateResources. After setting this to True, any changes to DataTemplate resources in the dictionary will cause all ContentPresenters in the scope of the dictionary to re-evaluate their choice of DataTemplate. This is a moderately expensive process – our recommendation is to not to enable it unless you really need it.
WPF – Distinguishing dynamic values in a template
This feature enables a caller to determine whether a value obtained from a template is “dynamic”. Diagnostic assistants, such as Visual Studio’s “Edit-and-Continue” facility, need to know whether a templated value is dynamic, in order to propagate a user’s changes correctly.
The feature is implemented by a new method on the class DependencyPropertyHelper:
This returns true if the template’s value for the given property is “dynamic”, that is if it declared via DynamicResourceReference or TemplateBinding, or via Binding or one of its derived classes.
WPF – SourceInfo for elements in templates
Diagnostic assistants such as Visual Studio’s “Edit-and-Continue” facility can use SourceInfo to locate the file and line number where a given element was declared. The SourceInfo is now available for elements declared in a template loaded from XAML (as opposed to compiled BAML). This enables diagnostic assistants to do a better job. This feature is enabled automatically whenever SourceInfo itself is enabled.
WPF – Enable Visual Diagnostics
This feature provides a number of ways to control the VisualDiagnostic features. Diagnostic assistants can request WPF to share internal information. This feature gives both the assistant and the application developer more control over when this sharing is enabled.
The VisualDiagnostic features in WPF, with their introduction in .NET Framework 4.6, were initially only enabled when a managed debugger was attached. However, scenarios have arisen involving other components (besides a debugger) that can reasonably be considered as a diagnostic assistant, e.g. Visual Studio’s design surface. Thus, the need for a public way to control the features. The feature is controlled by two new methods on the class VisualDiagnostics, and by a number of registry keys, app-context switches, and environment variables.
The methods enable and disable the VisualTreeChanged event. You can only enable this event in a “diagnostic scenario”, defined as one of the following:
- A debugger is attached
- Windows 10 Developer Mode is set. More precisely, registry key HKLMSOFTWAREMicrosoftWindowsCurrentVersionAppModelUnlockAllowDevelopmentWithoutDevLicense has value 1
- Environment variable ENABLE_XAML_DIAGNOSTICS_VISUAL_TREE_NOTIFICATIONS is set to a value different from “0” or “false” (case-insensitive).
Changes to the visual tree are disallowed while a VisualTreeChanged event is in progress. Specifically, an InvalidOperationException is thrown by any of the following actions:
- Changing a visual or logical parent
- Changing a resource dictionary
- Changing a DependencyProperty value on a FrameworkElement or FrameworkContentElement.
This guards against unexpected and unsupported re-entrancy.
It is possible to override this InvalidOperationException, should you encounter a situation where debugging is impeded by it. To do so, add the following AppContext Switch to the <runtime> section of the app config file and set it to true,
Switch.System.Windows.Diagnostics.AllowChangesDuringVisualTreeChanged
None of the features mentioned here are supported in production applications. They are intended only for diagnostic assistance.
Finally, you may want to run your application under the debugger, but in “production mode” without any potential interference from the VisualDiagnostic features. To do so, add the following AppContext Switch to the <runtime> section of the app config file and set it to true,
Switch.System.Windows.Diagnostics.DisableDiagnostics
Closing
Try out these new features in .NET Framework 4.7.1 Early Access build shared and please provide your feedback by reporting an issue at the .NET Framework Early Access GitHub repository. Stay tuned for further feature overviews in .NET Framework 4.7.1.