Creating Accessibility-aware Silverlight 2 Content (Cont.)
Ensure Keyboard Interactivity
Creating an accessible Silverlight application means creating a keyboard-accessible application. Try using your application with only a keyboard to identify where functionality is unavailable to keyboard-only users. Sometimes you'll find that you require mouse actions to use certain features. Other times you'll find that you cannot tab to an element.
With Silverlight, you provide alternative accessibility information by using the AutomationProperties static class and attached properties.
By thinking about keyboard accessibility during application design and development, you will avoid these types of issues. For more information on keyboard best practices, see Guidelines for Keyboard User Interface Design in MSDN (http://msdn.microsoft.com/en-us/library/ms971323.aspx).
IsTabStop and Tab Order
With the new keyboard and focus model in Silverlight 2, you can create a keyboard-friendly experience. You specify what controls can receive focus via the IsTabStop property. Most Silverlight controls, such as Button, already set the IsTabStop property to true. After you design the UI, take the time to set the TabIndex property to control the tab order. One thing to note is that only Control-based elements can receive focus.
Image and TextBlock (Non-Control-based Elements)
If you don't think about keyboard accessibility, you might add interactivity to an Image, Path, or MediaElement with mouse input, but visual elements that don’t derive from the Control class cannot receive focus. When you enable mouse actions on these types of elements, you may also want to enable the functionality with a keyboard command or with a control in the UI.
Alternatively, if you want to enable focus on an Image, you can create a custom UserControl element that contains the Image and add your keyboard logic there. Do note that you will also need to provide a focus visual indication, as described later in this article.
Custom Keyboard Actions
The trick in providing custom keyboard actions with a hotkey combination is to make sure your combination doesn't conflict with the browser keyboard actions because the browser will always win.
A good keyboard combination that I've used is combining a number key with Shift and Control keys. For example, to provide keyboard hotkeys for a particular view in my UI, I listen (hook up event handlers) for the Shift, Control, and number keys associated with the view. I add a KeyDown event handler to the root visual of my application since keyboard events bubble when not handled:if (e.Key == Key.D1 &&
(ModifierKeys.Control | ModifierKeys.Shift)) ==
(ModifierKeys.Control | ModifierKeys.Shift)))
// Perform hotkey action here
Regardless of what custom keyboard actions you add you need to let users know that they exist. You can do this by setting the AutomationProperties.AcceleratorKey property. In addition, you should add a tooltip or UI that describes the hotkey combination.
With Great Power Comes Great Responsibility
As you develop a great UI with complex gradients and cool graphics, you need to ensure you have a good experience with high contrast settings. I won't go so far as to say you shouldn’t make your UI cool; just put in the extra effort to make an accessible experience. Here are a few things to think about:
- Design with accessibility in mind.
- Support different text sizes or browser zoom.
- Honor high contrast settings.
Design with Accessibility in Mind
Using XAML and styling your application is great, but you can create some ugly UI that doesn't present well to users who need higher contrast for readability.
One important thing you can do during your design is to convey information with visual cues other than color. For example, if you highlight particular list items with a red font, you could also bold them, so the user has a non-color cue to distinguish highlighted items. You can optionally add some sound as the user moves over list items to note that the list item is "active".
To help you understand some of the ways people might use your application, think about what your application would look like if you printed it on a grayscale printer. Think about what it would be like to use it with the keyboard only. Think about whether your application is useable with the sound turned off. Finally, think about whether you could easily explain how to use your app over the phone. All of these will help your design be more usable for more people in more situations.
Support Changing Font Sizes
Silverlight 2 doesn't automatically change size based upon the computer's DPI settings nor does the content automatically change size based upon the browser's zoom or text size settings. There are three ways that you can scale your content to ensure your application can provide a large font experience: based upon the Web browser's zoom setting, based upon a user-selectable UI, and based upon a use-selectable font size UI. The last option only focuses on scaling the text size vs. scaling the whole UI.
Creating an accessible Silverlight application means creating a keyboard-accessible application.
Modern Web browsers have support for whole page zooming. When users zoom, the Silverlight browser plug-in receives a resize event. Silverlight provides a public Resized event that, with a little code in your application’s Loaded event, you can use to dynamically resize your Silverlight content:App.Current.Host.Content.Resized += new EventHandler(Content_Resized);
In the XAML, just put a ScaleTransform that you will use when the Silverlight plug-in resizes: <UserControl.RenderTransform>
<ScaleTransform x:Name="zoomTransform" ScaleX="1" ScaleY="1"/>
Lastly, apply the scale as a factor of your application’s size:void Content_Resized(object sender, EventArgs e)
System.Windows.Interop.Content content = App.Current.Host.Content;
double scalePlayerX = (content.ActualWidth / this.Width);
double scalePlayerY = (content.ActualHeight / this.Height);
this.zoomTransform.ScaleX = scalePlayerX;
this.zoomTransform.ScaleY = scalePlayerY;
A second approach is based upon the same code that you use for scaling based upon the Web browser's zoom except you provide your own UI for scaling.
The last approach is to provide an option to increase the font size. Silverlight 2 does not recognize the browser's text size settings, so you need to provide the user with a custom UI (as simple as a set of buttons for selecting text size). Adjusting the font size can be a great approach if you have a lot of text and the overall UI doesn't need scaling. Since adjusting the font size causes the text to take up more space, you need to use layout elements such as Grid and StackPanel instead of hard coding widths/heights. Silverlight elements inherit the FontSize property throughout, so setting it at the root of your application causes the value to propagate.
Bring Contrast to Your UI
Supporting high contrast is an important part to making your application accessible. Silverlight 2 provides the SystemParameters.HighContrast value to indicate when you should render in a high contrast mode. A high contrast mode can be as simple as omitting non-important images, gradients, or patterns behind text to more complex styling that makes your application design a bit simpler. In addition, a high contrast mode should remove or reduce transition animations, including the use of flashing.
You can take advantage of Silverlight's styling system to provide additional styles for use in high contrast scenarios. Silverlight 2 does not ship with high contrast styles for built-in controls, so you will need to create this as you style your application.
Expression Blend provides support for creating custom styles for your controls. I recommend creating two styles that you can switch between based upon the SystemParameters.HighContrast value. There is one catch: you can only apply a Silverlight control style once, and it has to be before or during the control's constructor. The more holistic approach is defining custom control styles during application startup, but you can apply a custom style in your control's constructor as well:public class MyButton : Button
this.Style = (Style)Application.
For an example of a Silverlight control "theme" framework, see Nikhil Kothari's blog for details (http://www.nikhilk.net/Silverlight-Themes.aspx).