Techniques for WCAG 2.0

Skip to Content (Press Enter)

Silverlight Techniques for WCAG 2.0

This Web page lists Silverlight Techniques from Techniques for WCAG 2.0: Techniques and Failures for Web Content Accessibility Guidelines 2.0. Technology-specific techniques do not replace the general techniques: content developers should consider both general techniques and technology-specific techniques as they work toward conformance.

Publication of techniques for a specific technology does not imply that the technology can be used in all situations to create content that meets WCAG 2.0 success criteria and conformance requirements. Developers need to be aware of the limitations of specific technologies and provide content in a way that is accessible to people with disabilities.

For information about the techniques, see Introduction to Techniques for WCAG 2.0. For a list of techniques for other technologies, see the Table of Contents.

Table of Contents


Silverlight Technology Notes

Microsoft Silverlight is a development platform for applications. To learn more about Silverlight and how Microsoft defines and markets the Silverlight technology, see What Is Silverlight? document on microsoft.com.

Once an application author produces a Silverlight application, the most common way to deploy that application is to present the Silverlight content using a browser plug-in that end users have installed on their computers. The Silverlight plug-in is instantiated within an HTML page as an <object> or <embed> tag. <object> tag attributes reference Silverlight's unique classid, and/or its MIME type, thus invoking a plug-in instance within the browser host's HTML content. Users request the Silverlight-containing page as a URL, and the surrounding HTML plus the Silverlight content is viewed within a browser host such as Firefox, Internet Explorer, Google Chrome, or Safari. There are other means by which Silverlight-developed content can be deployed that are NOT viewed in the plug-in or hosted by HTML; this is discussed in the upcoming section "Browser Host Platform Considerations".

The content that is displayed within the Silverlight content area is specified as the "source" parameter, within the Silverlight object/embed tag. The "source" parameter value references a URI for a package. The package is typically served by the same server that served the HTML (and the package itself is typically requested through http: or https: protocol). The package always contains an application manifest, and a managed code compiled DLL. The package might also contain other content, for example media files or image files that the application consumes as resources. The compiled DLL typically contains two types of information within its compiled structure: CLR runtime code that handles dynamic operations of the application such as startup logic, business rules, event handlers, and further resources. The resources inside the DLL are primarily UI definitions in a markup format/language called XAML.

Silverlight provides a combination of built-in support for accessibility and capabilities that authors and authoring tools can take advantage of in order to enable support for accessible content. Tools and related technologies that are related to this include:

  • Microsoft Visual Studio 2010 (or Microsoft Visual Studio 2008 if still developing for version 3 of the Silverlight runtime) – Silverlight authors can use Express versions if their development needs are fairly basic

  • Microsoft Expression products, in particular Microsoft Expression Blend

  • Silverlight Tools – a separate package for Visual Studio that should be installed for effective Silverlight application development

  • Developer tools that are specifically for verification of information presented to either the UIA or MSAA accessibility frameworks.

Accessibility Frameworks

Silverlight support for assistive technologies is based on implementing Silverlight for Microsoft UI Automation (often abbreviated as UIA). In the UIA accessibility framework, Silverlight is implemented as a UI Automation server. This means that Silverlight provides information about the application itself and its current content through the framework. Any subscriber to the operating system's automation can consume that information as a UI Automation client. One such client role is typically implemented by assistive technologies, most notably by screen readers. By acting as a UI Automation client, an assistive technology can programmatically determine many aspects of Silverlight content and content structure. In addition, UIA has APIs that can change the content in a predictable way that maintains security boundaries between applications. Reading information from Silverlight through the UIA accessibility framework requires no extra work on the part of a given assistive technology, presuming that the assistive technology has already implemented UIA. All information that Silverlight reports to UIA comes through the common property set, and a fixed set of possible user interactions is programmatically accessible through a discoverable set of automation patterns and techniques.

As an example of how UI Automation might provide information to an assistive technology, consider the following scenario:

  1. A Silverlight application author produces an application that follows all Microsoft-documented best practices for providing accessibility information, either by specific programming actions or by relying on a known set of Silverlight default behaviors (many of these actions/behaviors are also described as Silverlight WCAG techniques).

  2. A user views a Web page that contains Silverlight content, using a browser host that loads the HTML, and using an operating system such as Microsoft Windows (XP, Vista or Windows 7) that supports UI Automation.

  3. An assistive technology that is already running on the user's system loads the UIA representation of all Web content loaded by the browser. Part of that representation is an automation element that represents the Silverlight plug-in. The plug-in content area itself is focusable in the browser host's HTML rendering and representation model.

  4. The user navigates elements in the Silverlight application area, either by using the TAB sequence, or by using navigation techniques implemented by a particular assistive technology.

  5. By forwarding information that is pertinent to either the navigated-to element or the application in general, the accessibility framework provides the assistive technology with the information from Silverlight application. As a specific example, a screen reader might read the name and role of the currently focused control element such as a Silverlight TextBox. In addition, the assistive technology can provide means to enter data or otherwise interact with elements of that application, if that element reports to UIA that it supports such interaction.

A good introductory topic on UI Automation is available on MSDN.

UI Automation supersedes Microsoft Active Accessibility (MSAA), an earlier Microsoft accessibility framework. UI Automation provides built-in bridging support for MSAA, such that assistive technologies that are implemented as clients for MSAA rather than UIA receive the expected interface hooks for IAccessible and can call methods of the MSAA interfaces. Also, applications that provide MSAA/ IAccessible are readable to a UIA-client assistive technology through similar bridging.

Whether implemented as clients for UI Automation or for MSAA, support for assistive technologies is provided for users viewing content using combinations of:

  • Microsoft Internet Explorer 6 or later, in combination with Microsoft Silverlight on Windows.

  • Mozilla Firefox 3 or later, in combination with Microsoft Silverlight on Windows.

  • Google Chrome 4 or later, in combination with Microsoft Silverlight on Windows

Screen reader assistive technology support for either MSAA or UIA is provided in several assistive technologies, including but not limited to:

  • JAWS

  • Windows-Eyes

  • NVDA

  • Microsoft Narrator

The exact level of support to assistive technologies will partially depend on whether that assistive technology is implemented as a UIA client or an MSAA client. This can vary depending on specific version releases of the assistive technology. In general, the UIA architecture is capable of reporting a richer information set to clients than is MSAA. This is because UIA has a larger number of properties available, and also because UIA has the patterns concept to support class extension whereas MSAA does not (class extension is a key concept in Silverlight programming).

Silverlight uses UI Automation support as a general system that addresses parts or entireties of many WCAG criteria at a system/platform level, rather than requiring each Silverlight author to build the entirety of such support as an individually coded feature of a Silverlight application. The following is a list of criteria where UI Automation support in Silverlight is necessary to apply the Silverlight WCAG techniques, and the application must be on a client and platform that also supports UIA (or MSAA):

The following is a list of criteria where UIA Automation support in Silverlight is helpful but not necessary:

Further notes on Name Role Value

Success Criterion 4.1.2 (Name Role Value) directly influenced the design of both the Microsoft UI Automation accessibility framework and its MSAA predecessor. Many aspects of providing name, role and value are built-in to the Silverlight UIA support, and that information can be programmatically determined by assistive technologies that are programmed as UI Automation clients.

Name

In most cases, the name of the control is used to identify that control to users, as well as providing a programmatic identifier. In UI Automation programming, any entity that can have a name is represented as an AutomationElement, and its name is determined by reading the value of the AutomationElementInformation.Name property. There is an intermediate "Current" property, so an example usage is something like:

string AName = anAutomationElement.Current.Name;

Name is the most common UI Automation property that is consumed by assistive technologies. Application authors in general that rely on UI Automation (and Silverlight application authors in particular) typically provide strings for Name that can inform users of the purpose that the element serves in the application. For example, if an application provides a button that can be activated, the Name reported to UI Automation could best describe its purpose by using a Name string something like "Submit form". While there is some crossover here with the concept of Value, what is notable about Name is that it is controlled only by the application rather than typical means of user input that would alter the data of Value.

Because UI Automation is also used as a framework for automation testing of applications, UI Automation supports a parallel identification property named AutomationId. AutomationID is not relevant to accessibility support scenarios, although in practice Name and AutomationID sometimes use the same string values, or are supported by parallel property-forwarding techniques by implementing technologies. The intended design difference between AutomationId and Name is the following:

  • AutomationID is not intended to be human readable, but is intended to be unique

  • Name is intended to be human readable but might not be unique

Silverlight in particular has a property-forwarding technique whereby the Silverlight-specific Name or x:Name properties are promoted as the initial AutomationElementInformation.Name. This forwarding is implemented within build procedures to provide a fallback for testing and initial development of an application's UI Automation representation. In many cases a forwarded Name/x:Name does not result in a particularly human-comprehensible or user-actionable string or phrase. Silverlight application authors should use a test-based methodology to examine all possible AutomationElementInformation.Name values exposed by their application, and assure that each such string is specifically replaced by a UI-specific AutomationProperties.Name value.

Role

Role in UI Automation can be determined through several techniques.

The most straightforward technique for determining a given AutomationElement's role is to check the value of ControlType. This value provides an enumeration that reports role as several known possibilities plus an alternate role of "Custom" if no enumeration-defined role is a good descriptor. For example, a Silverlight Button control describes itself to UI Automation as a ControlType of Button, and a Silverlight TreeView describes itself as Tree.

For further information on roles, UI Automation clients can query an AutomationElement to see which UI Automation patterns that element supports. The patterns describe expectations of the interaction model, and the patterns themselves expose the methods that clients should call to engage that interaction. For more information, see Get Supported UI Automation Control Patterns on MSDN.

Value

In MSAA, the "Value" concept was addressed by the simple property Value and had to be represented as a string. One of the major refinements of UIA over MSAA is to expand what types of data can be expected to exist as a value. For this reason, determining "Value" requires a larger understanding of UI Automation and how to access UI Automation patterns exposed by each peer, and is not discussed further in this document. For more information, see Get Supported UI Automation Patterns and UI Automation Control Patterns for Clients. The most basic concept of Value is often represented by the ValuePattern, but UI Automation clients should be aware of the larger range of patterns that can possibly return or provide a value. In general, the UIA Value pattern is only relevant for setting the value directly, such as in a text box where a user types or otherwise inputs a string or phrase.

State is also a related concept to value. UI Automation elements typically report states that make sense given their role, and such state is reported in the provider implementations. There are also some generalized state properties available in any automation element. Examples of these include: HasKeyboardFocus; IsOffscreen.

Object Tree Concepts and UI Automation Tree Views

The object tree is composed of all the programming constructs that a Silverlight application author explicitly declares by writing XAML UI definitions (which are initially loaded by the Silverlight runtime) and by invoking run-time code. The relationships between nodes in XAML markup, and the declaration order of peer elements in XAML, create identical relationships/orders in the object tree representation. In code, order is made explicitly by using structured definitions and APIs of various types of collections (list, dictionaries, etc.) that are common in .NET Framework programming. For example, to get the first child of a StackPanel named myPanel, call myPanel.Childen[0] (.NET collections are zero-index based). Parent-child relationships are declared by how specific properties are set. For example, to add a "newButton" child element to myPanel as the last child, call myPanel.Children.Add(newButton).

An object tree representation forms the basis of the Silverlight run-time programming model, and enables programmatic access to every programming entity or element part of a running Silverlight application. The object tree representation is particularly useful for accessibility frameworks, and in turn for assistive technologies that use the accessibility framework as a client. The relationships and item order in the object tree also define the default reading order, as well as the default tab sequence for default Silverlight key handling. The Silverlight plug-in code that renders Silverlight content into the plug-in display area is literally reading the same run-time object tree that is being simultaneously reported to the accessibility frameworks or other subsystems of Silverlight (for example, printing APIs).

Silverlight supports UI Automation (UIA) as its primary accessibility framework on Windows platform. Silverlight also provides accessibility information to MSAA, by reporting information through the UIA-MSAA bridge. By using the APIs of the relevant accessibility framework, assistive technologies and other accessibility framework clients can discover the information and relationships declared in a Silverlight application's runtime object tree. The accessibility framework APIs work against the UI automation tree in a manner that does not require any specific knowledge of the Silverlight programming model. For example, the UI Automation APIs use an abstraction of a UIAutomationElement to represent any accessible Silverlight object. By calling UI Automation APIs against this abstracted object, accessibility framework clients can determine any child elements and their count, check parent elements, can obtain name/role/value of that UIAutomationElement, and so on. In fact, Silverlight accessibility support in general is achieved without assistive technologies even being aware that Silverlight is a distinct technology from HTML. This is because Silverlight implements its accessibility framework support such that Silverlight dovetails into the surrounding HTML content through the connection point of the "SilverlightControl" UIAutomationElement that exists within the browser host's HTML content.

For more information, see UI Automation (unmanaged) or UI Automation (managed)

An Object Tree / UI Automation Example

In the following XAML example, a Silverlight StackPanel is the container element for four different Button elements. In the visible user interface, the resulting buttons are oriented vertically, with the first declared button vertically above the others and first in the tab sequence. (Event handling logic for each button is not shown and is not relevant for the example.)

<StackPanel Orientation="Vertical" > <Button>Hit</Button> <Button>Stay</Button> <Button>Split</Button> <Button>Double Down</Button> </StackPanel>

The following image shows the resulting render order. Note the first “Hit” button has the blue border as focus indicator; focus was placed here by traversing the default tab order, and this element was the first Silverlight element that captured the focus.

Image:StackPanelButtonsOrder.png

The following is the same UI as defined in C# code rather than XAML. The key concept here is that each call to a Silverlight collection Add method adds that item to the end of the existing collection. Thus, to define a collection’s order, add the intended first item with the first call to Add, the second item in the next line of code, and so on. This code is analogous to what a XAML parser does when it processes the previous XAML example, and results in the same visible UI and same default tab order.

void MakeUI() { StackPanel sp = new StackPanel() { Width = 300, Orientation = Orientation.Vertical }; Button hitButton = new Button() { Content = "Hit" }; Button stayButton = new Button() { Content = "Stay" }; Button splitButton = new Button() { Content = "Split" }; Button doubleDownButton = new Button() { Content = "DoubleDown" }; sp.Children.Add(hitButton); sp.Children.Add(stayButton); sp.Children.Add(splitButton); sp.Children.Add(doubleDownButton); }

The following is a screenshot of the UI Automation subtree specifically in the area of the UI as declared by either the XAML or C# shown previously. The tool being used in this screenshot is Inspect.exe, which comes with the Windows SDK version 7.1

Image:Screenshot_uia_objecttree.png

The screenshot is representative of the kind of tree structure that a UI Automation client such as a given assistive technology is able to program against, when a Silverlight application exists as an embedded plug-in inside the surrounding browser host.

Input and Multimedia

Silverlight implements UI controls that support keyboard input methods for users who do not use a mouse. Also, Silverlight provides the input system framework such that application authors and control authors can provide similar mouse-keyboard equivalence from their own UI, by using the Silverlight event system and sending each event to the same or similar handling logic. Silverlight application authors can control the tab order of content within Silverlight content, as is demonstrated in the WCAG 2.0 techniques for Silverlight.

Silverlight is often used to display video. Silverlight and the media formats it supports can include embedded text tracks with timing markers. The text tracks and timing markers enable a Silverlight technique that can provide closed captions or subtitles in any language. Silverlight and its media formats also support multiple tracks of audio, thereby enabling support for video description.

Text and Color Preferences

Silverlight supports text resize through browser zoom, as described in G142: Using a technology that has commonly-available user agents that support zoom. The effects of invoking browser zoom apply any resize to the entirely of the hosted HTML (including Silverlight content). Silverlight interaction with browser zoom is further discussed in the Silverlight WCAG technique SL22: Supporting Browser Zoom in Silverlight.

However, not all browser hosts that are supported by Silverlight provide browser zoom as a feature, and in the Firefox implementation the text within the Silverlight content area is not affected if the user has checked Zoom Text Only. As an alternative or additional technique for text resize, the Silverlight WCAG technique SL23: Using A Style Switcher to Increase Font Size of Silverlight Text Elements describes how to use Silverlight APIs to resize text elements that are specifically within the Silverlight content area.

Silverlight supports a high-contrast detection mode at the platform level. If the user has already selected a high-contrast mode at the platform/OS level, the Silverlight application can use various styling and appearance techniques to select a color scheme that is appropriate for high contrast. This concept is shown in the Silverlight WCAG technique SL13: Providing A Style Switcher To Switch To High Contrast. Silverlight and its API do not account for any color settings that are made for default HTML by a browser host application (settings under General / Appearance in Internet Explorer; settings under Content / Fonts & Color in Firefox). This information is not made available to plug-ins such as Silverlight.

User Agents Supported

Silverlight documents its official list of supported user agents on the Microsoft.com web site. The list is dynamic, because the vendors that produce browsers are constantly updating versions. Also, Silverlight might announce support for a browser in a time period that falls after the release date of the latest Silverlight runtime; sometimes this means that the Silverlight product team performed new testing for acceptance of that specific user agent and can now vouch for an official level of Microsoft support.

For convenience, a snapshot of the official Microsoft browser/user agent support matrix from the date 13 January 2011 is reproduced here:

  • Windows Vista: IE 8, IE 7, Firefox 3, Chrome 4

  • Windows 7: IE 8, Firefox 3, Chrome 4

  • Windows Server 2008: IE 8, IE 7, Firefox 3, Chrome 4

  • Windows Server 2008 R2: IE 8, Chrome 4

  • Windows Server 2003, Windows XP SP2, SP3: IE 8, IE 7, IE 6, Firefox 3, Chrome 4

  • Windows 2000 SP4 + KB 891861: IE 6

  • Macintosh OS 10.4.11+ (Intel-based): Firefox 3, Safari 3, Safari 4

For the official list of supported user agents for Silverlight, see http://www.microsoft.com/getsilverlight/get-started/install/default.aspx (System Requirements tab).

  • As of 13 January 2011 Silverlight does not work in 64-bit browser hosts (64-bit platform users should use a 32-bit browser application on their system).

  • Silverlight and Novell have a technical collaboration, and Novell sponsors an open-source initiative known as the Mono Project. Part of the Mono Project is Moonlight, which is a port of Silverlight technology for Linux and other Unix/X11 based operating systems. For more information, see Mono and Moonlight Supported Platforms.

Browser Host Platform Considerations

Depending on the browser host being targeted, Silverlight is implemented as an ActiveX control or as an NPAPI plugin. When a user installs Silverlight, they are installing both of these implementations, such that the same Silverlight installation could be accessed by an Internet Explorer browser host and a Firefox browser host, and could even be accessed simultaneously by both. Differences between the program access layers of ActiveX versus NPAPI, and also browser-specific differences in program access layers, produce some platform differences that occasionally relate to accessibility support. For example, there can be slight differences in whether the program access layer will correctly forward certain keys or key combinations, which might impact keyboard-mouse equivalence implementations.

Silverlight also supports modes that do not rely on a browser host at all. In previous releases of Silverlight, Silverlight was defined as a platform for producing rich Internet applications. This is still true, but in the current Silverlight release the deployment options are expanded such that a Silverlight application is not necessarily a web-based application, and Silverlight is not exclusively a Web content technology.

Silverlight supports an out of browser deployment mode. Through UI in an initial Web-based Silverlight application, the user is asked to conform whether they wish to install the out-browser application. If the user approves the installation, the Web-based Silverlight application shuts down and the installation begins. Typically, the application restarts itself immediately after the installation. Once installed on the user's hard disk, a Silverlight out-of-browser functions more as an application window under the control of the current platform operating system. This is manifested through technical aspects such as a change in programming security boundaries, and addition of operating-system-specific application model features for the Silverlight out-of-browser application. Examples of the latter include icons and presence in running-application UI metaphors such as task bars. Out-of-browser mode is not specifically mentioned in the Silverlight WCAG techniques, because in this mode Silverlight is no longer a Web application. However, an out-of-browser Silverlight application can include an embedded control that is itself capable of displaying HTML. In this situation, Silverlight accesses basic HTML browser frameworks provided by the platform, and any techniques that would normally apply to HTML content and Web content could also apply to the HTML as viewed within a Silverlight out-of-browser application. For more information, see MSDN.

Silverlight is also a development platform that can be used to create applications for Windows Phone. While these applications often rely on Internet connectivity, these applications are run in the context of an application directly under the Windows Phone operating system, rather than being run in an intermediate Web host that serves as a generalized Web browser for Windows Phone. Therefore the typical considerations of Silverlight acting as a part of a larger definition of Web content do not apply. For more information on Silverlight for Windows Phone development, see The Silverlight and XNA Frameworks for Windows Phone on MSDN.

The XAML Language

XAML is an abbreviation for eXtensible Application Markup Language. In the Silverlight application model, XAML is generally used for defining the elements that make up an application's user interface (UI). XAML markup for UI resembles markup paradigms for HTML in that it uses angle brackets in its syntax, has concepts of elements and attributes, and uses a predominately text-based file editing and storage format such that XAML is human-readable in a text editor. The UI design role typically designs an application user interface by interacting with graphical user interface tools such as Microsoft Expression Blend. In this case, Expression Blend produces XAML as its output, and XAML becomes the interchange format between the Expression Blend tool and the Visual Studio tools. Visual Studio is more typically used by code-oriented Web developers for Silverlight. Web developers in Visual Studio might work with XAML at the text level, and write or change the XAML markup, and more than one interchange between tools and/or roles of a given XAML file might occur by the time the application is finished. The Silverlight techniques are written from the perspective of the code-oriented Web developer who is possibly adjusting post-design phase XAML.

One key difference between HTML and XAML is that XAML is always interpreted by the Silverlight runtime, or preparsed at compile time within Silverlight tools. XAML is NOT parsed by potentially different engines per browser host. Because XAML provides UI definition, the Silverlight techniques often include procedures or concepts that adjust the elements and attributes of XAML markup for an application. Some of the techniques show procedures or concepts for code-behind, scripting, deployment steps, or other aspects of Silverlight programming in addition to or instead of XAML examples. The runtime parsing characteristics of XAML for Silverlight is discussed further in the Silverlight WCAG technique SL33: Using Well-Formed XAML to Define a Silverlight User Interface.

XAML attributes sometimes specify strings that are visible in UI and reported to assistive technologies. The Silverlight WCAG techniques typically hard-code such UI strings in XAML, so that the example code can be kept simple and can concentrate on the immediate concept being illustrated. However, hard-coding UI strings in XAML is not a best practice for production code, because of localizion considerations. To learn more about producing XAML that is localization-ready, or about refactoring XAML to support better designer-coder-localizer workflows, see Localizing Silverlight-based Applications on MSDN.

Test-based Methodology for Accessibility Support

Some of the Silverlight WCAG techniques mention a concept of "test-based methodology" - this section describes what is meant by that concept.

In typical Web application development, there are phases that are a natural part of the workflow. First there is a specification phase, where the basic planning is performed. The next two phases are user interface design (often interweaved with user experience design) and code development. For larger applications or applications that are built on frameworks, the human role of designer is often separate from the human role of code developer/script developer. For this reason the UI design phase and code phase might be going on concurrently, and/or might be iterative. At the point where the efforts of UI design and code development are combined into a working application, many Web developers now introduce a testing phase. It is at this point that a test-based methodology for accessibility support becomes an appropriate and useful strategy.

Testers for Web applications sometimes rely largely on ad hoc or experiential tests, but increasingly there are tools available that assist with the job of testing a Web site. Many of these tools focus on specific aspects of testing: sub-areas such as testing under specific browser hosts; testing with stored state or data vs. initial experience; testing for different form factors; etc. One such sub-area of testing is testing the existing accessibility support.

Because Silverlight supports the UI Automation accessibility framework, the best tools for testing accessibility support in a Silverlight application are the tools that work with UI Automation as their basis. Some of these tools are available from Microsoft, and other such tools are available from third parties.

In a test-based methodology, a tester should view the application in its UIA representation. Using tools, testers can write tests for certain conditions and determine whether the application as a whole passes or fails. For example, a scripted test could determine whether all the controls in a UIA view have a valid string for Name. No Name string would potentially cause an assistive technology to misrepresent that element, and could cause confusion for user groups that rely on a particular assistive technology view of an application. In cases where an application failed these kinds of tests, the application might be sent back to the human role of developer/script writer, so that the missing accessibility information can be committed to the application code base. Then the application can be re-tested.

A test-based methodology for accessibility support works best because Silverlight is such an extensive development platform. Sometimes it is not immediately obvious to a developer that a certain property required for accessibility remained unset. Or perhaps that developer was expecting that the human design role would have introduced that information as part of UI definition. Only when the integration of UI design and code is complete is it possible to see that there is still information or functionality missing. When the development process includes a testing step wherein dedicated tests for accessibility support are committed in a systematic way, it is much more likely that issues can be detected prior to application deployment.

Running Silverlight Test Files Provided with Techniques

Most Silverlight WCAG Techniques reference one or more ZIP files from the Test Files section of the technique. These ZIP files are linked from the techniques and can be uploaded for testing.

To run the test files, you must have Microsoft Silverlight (the client run-time version) installed on your computer. To install Microsoft Silverlight, open the following URL: http://www.microsoft.com/getsilverlight/ . Follow the instruction steps on the Web page. When you install Silverlight, you are installing the plug-in for use by all supported browser user agents on that computer. In order to test techniques that rely on UIA, you should install Silverlight on a computer that is running Microsoft Windows (XP SP2; Vista; Windows 7) as the operating system. Note that you must be running as adminstrator in order to install Microsoft Silverlight on the computer.

Each ZIP file contains two items: an HTML file, and a Silverlight package file (always has a file extension of XAP). You can run any given test file through the following procedure:

  1. Click the link from the technique to download the ZIP file.

  2. Extract all files within the ZIP file to a temporary location, but use a tangible location such as C:\temp rather than temporary Internet files. Do not attempt to open the HTML file from within the unextracted archive; the test will only run correctly when the test components are extracted from ZIP.

  3. Go to the folder location where you extracted the files. To run the test based on the current system's file associations for HTML, open the HTML with the associated browser. Otherwise, you must open the specific browser you want to test under, and type or copy either a file:/// URL or a Windows folder path into that browser's address bar.

  4. This should open the HTML page. When the HTML page opens, it instantiates a Silverlight plug-in within the page content, which in turn references the other extracted file (the XAP) as local content.

  5. Once the content is in view, follow the remaining steps that are indicated in the specific test procedure.

Using Sample Code in Techniques to Create a New Silverlight Application

The Silverlight techniques offer pre-built test files so that you can observe the basic operation of a technique without having to write the code yourself, or create your own application. The salient parts of Silverlight code or Silverlight XAML for the technique are provided as code blocks under the Examples section. In order to experiment more with the technique beyond running the test file, you might want to define your own Silverlight application project, and then import the code and XAML from the technique into your own project. This section describes the basic information that is necessary to create a project that incorporates sample code from a Silverlight technique.

Prerequisites

Creating a Silverlight application project requires that you have a full Silverlight application development environment installed. Although Silverlight applications run cross-platform, the actual development of Silverlight applications is done on Microsoft Windows computers. The computer must have Microsoft Visual Studio 2008 or Microsoft Visual Studio 2010 installed. With some limitations, the Express SKUs of Visual Studio are adequate for basic Silverlight application development. The Express SKUs are available for 30-day evaluation from the following URL: http://go.microsoft.com/fwlink/?LinkId=323467 . In addition to Visual Studio, you also should install the Silverlight Tools, which includes the Silverlight SDK. Get Silverlight Tools from http://go.microsoft.com/fwlink/?LinkID=177428. What to install for Silverlight development is also linked to and explained at Silverlight.net.

Creating the Project

For general instructions, see How to: Create a New Silverlight Project. This creates a new project based on a default template.

The C# code or XAML shown in the Silverlight techniques is a usually a fragment that you should integrate into an existing code file or XAML page from the default project template. For code, you generally open the file page.xaml.cs from Solution Explorer, and paste the entirety of the example code into the body of the C# public partial class that you start with (this class comes from a template). For XAML, you generally open page.xaml from Solution Explorer and paste the entirety of the XAML into the <Grid> element. In some cases the example XAML is the entire XAML (you can identify this case if the example XAML contains one or more xmlns attributes). In this case, replace the entirety of the XAML. However, you may have to adjust the value of the x:Class attribute to properly reference your own partial class; this name is influenced by your own project naming in your local project and thus cannot be anticipated by the example code. Descibing Silverlight application development in its entirety is well beyond the scope of this document. Use resources available from Silverlight.net or MSDN Silverlight documentation to learn more about Silverlight application development.

Special Considerations for WCAG 2.0 Compliance

2.4.2 Page Titled - In order to meet 2.4.2, Silverlight content must be embedded within an HTML page that has a page title in the HTML title element.

3.1.1 Language of Page - The language of an HTML page is established by the Lang attribute of the containing object element in HTML. However, Silverlight's own logic generally interprets language/culture information using a Microsoft .NET Framework concept of the CultureInfo object. This makes it important to align the HTML-level lang with any CultureInfo as used by Silverlight. The reason for this is that assistive technologies are likely to respect the top-level declaration of the Lang attribute and to not be aware of the CultureInfo considerations of embedded Silverlight content. Application authors can delibrately override language settings of a client by specifying a discrete CultureInfo in the Silverlight <object> parameters; this can be useful if the application has real-time language switching, if users store language preferences either locally or based on server information or cookies, etc. Aligning html-lang with CultureInfo and adjusting the CultureInfo through various means are both discussed in Silverlight techniques.


SL1: Accessing Alternate Audio Tracks in Silverlight Media

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL1. Also see Silverlight Technology Notes.

Description

The objective of this technique is to show how to access an alternate audio channel in a prepared media file that is played in a Silverlight MediaElement.

Silverlight supports media file formats that contains additional audio channels in synchronization, beyond the two tracks for stereo audio that are used by typical media player defaults. Silverlight provides a dedicated AudioStreamIndex API on MediaElement, so that the Silverlight application author can use Silverlight programming techniques to select which audio channel to play for the user. Silverlight control authors might label a UI control with text such as "Activate this button to listen to an audio-only version of the media presentation" so that the purpose of the media element control interface is clear to the user. That way the same media control can be used to present the media either as audio-video or as audio-only with alternate track depending on user preference at run time.

The media formats that are supported by Silverlight are documented on MSDN.

Media encoding

The process of encoding the media with additional audio channels is not described in this technique because configuring and encoding audio channels for media formats is a technique for any usage of media in a computer application, not just a Silverlight-specific technique or a Web technology technique. For more information on one possible procedure for encoding the media in WMV format, see Microsoft Expression Encoder Overview. Often, Silverlight authors will receive the media from a third party, such as a video production facility, and are not directly involved with the encoding process. Silverlight authors should verify that the media they are using has alternate audio tracks encoded in it. If such tracks exist, Silverlight authors will need a track listing from the media producer to know which of the audio tracks is intended as the alternate audio. Other tracks might exist in the encoded media that provide language translations of the default audio, or that serve other purposes.

Examples

Example 1: Changing AudioStreamIndex

This example has a UI definition in XAML and interaction logic in C#. In addition to the typical Play/Pause/Stop controls, this interface includes a Play Full-Description Audio button. Activating the button invokes a function that swaps the audio channels and plays an alternative synchronized audio channel that contains a composite full-description audio track.

The following is the basic UI in XAML. This example is deliberately simple and does not include AutomationProperties. Audio streams are identified by an index in a collection.

      <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="20" />
        </Grid.RowDefinitions>
        <MediaElement x:Name="media" Source="/combined.wmv"
           Width="300" Height="300" 
           Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
           AutoPlay="false"
        />
        <Button Click="StopMedia" 
     Grid.Column="0" Grid.Row="1" Content="Stop" />
        <Button Click="PauseMedia" 
     Grid.Column="1" Grid.Row="1" Content="Pause" />
        <Button Click="PlayMedia" 
     Grid.Column="2" Grid.Row="1" Content="Play" />
        <Button Name="AltAudioBtn" Grid.Row="2" HorizontalAlignment="Left" Grid.ColumnSpan="2" 
        Click="AltAudioBtn_Click">Play Full-Description Audio</Button>
    </Grid>

The following is the C# logic.

        private void AltAudioBtn_Click(object sender, RoutedEventArgs e)
        {
            if (media.AudioStreamCount > 1)
            {
                if (media.AudioStreamIndex == 1)
                {
                    media.AudioStreamIndex = 0;
                    (sender as Button).Content = "Play full-description audio";
                } else {
                    media.AudioStreamIndex = 1;
                   (sender as Button).Content = "Play default audio";
                }
            }
            else
            {
                (sender as Control).IsEnabled = false;
            }
        }
        private void StopMedia(object sender, RoutedEventArgs e)
        {
            media.Stop();
        }
        private void PauseMedia(object sender, RoutedEventArgs e)
        {
            media.Pause();
        }
        private void PlayMedia(object sender, RoutedEventArgs e)
        {
            media.Play();
        }

This example is shown in operation in the working example of Alternative Audio Channel. If using the test file, the test contains test audio tones rather than actual audio description, but the pitch of the tones is indicative of which of the channels is selected and played.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Open the HTML page for a Silverlight application, where that application plays media and the media is expected to support an alternate audio track for the video.

  2. Verify that the application user interface presents a control that enables the user to cause the media to play with an alternate audio track.

  3. Activate that control. Verify that the audio portion of the media player output as played through the computer's audio system is now playing the alternate audio track.

Expected Results

#2 and #3 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL2: Changing The Visual Focus Indicator in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL2. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the Silverlight "control skinning" scenario and feature set to change the visible focus indication of a control. In particular, the intent is to increase the visibility of focus indication versus the appearance of a default-styled control. This technique is useful both for the control sets that are included in the Silverlight run time or SDK assemblies, as well as for Toolkit or any third party distributed control.

The default Silverlight core controls all indicate some type of visible focus indication, through their default templates. However, Silverlight application authors can still use the skinning techniques to augment or replace the visible focus indications for controls as used in their applications. For more information on how Silverlight controls will generally supply a default visual focus indicator, see Focus Overview on MSDN.

Silverlight control skinning is enabled through a deliberate separation of UI and logic in the Silverlight control model. Appearance of a control is largely written in XAML. The logic is largely written in code (for example C#) and is left unaffected when a Silverlight application author provides a new control template "skin". The hooks that connect the appearance and the logic are a Style property of the control (which the author changes the value of, to refer to their new XAML resource) and a contract of expected named entities in the XAML. The control logic invokes the names of the entities/parts whenever control state changes, and the expectation is that the named part provides the necessary appearance as defined in XAML. Design tools such as Visual Studio or Expression Blend generate copies of the default templates and parts, such that Silverlight authors can modify the parts that they want to change the appearance of, and still preserve the remainder of default appearance and behavior of the control.

For the visible focus indicator technique, the author typically modifies a single visual element that renders in layout as an overlay on top of the control when it is focused, and switches the overlay to nonvisible when the control is not focused. This element is a named element that is typically referred to from within the XAML named state Focused, which in turn is hooked up to changes in the visual state.

Note that this technique assumes that the original control author provided the necessary logic event hookup, and exposed a named state associated with keyboard focus to work with. If this is not the case, or if the scenario is that a Silverlight author is defining their own control, a different technique is needed. See SL7: Designing a Focused Visual State for Custom Silverlight Controls.

Focus in Silverlight

Focus in Silverlight is equivalent to the larger user interface and application concept of keyboard focus. The element that has focus is the element within the Silverlight object tree and programming model that has first chance to process the Silverlight key events. As a more tangible example that is user-centric, if a TextBox has keyboard focus, then when the user presses keys on the keyboard, the characters associated with the user's pressed keys will appear in the TextBox. A user interface element in Silverlight can obtain keyboard focus in one of three ways:

  1. The user uses the Silverlight tab sequence to traverse into the Silverlight content and to focus a specific control.

  2. The Silverlight application's logic calls the Focus method programmatically to force focus to a control.

  3. The user performs some other action, for example uses the mouse to click on a control. That control's specific logic handles the Silverlight input event and uses that event as stimulus to call Focus on that control. The difference between this case and the above case is that the behavior is typically built-in to that control's runtime behavior, and does not require each application author to call Focus in application code.

Examples

Example 1: Two Button elements, one reskinned to provide new visible focus indicator

XAML templates can be verbose; for clarity, only the parts of the template that were changed or useful for showing the structure are shown. Omitted portions are shown as ellipsis (...).

<UserControl x:Class="VisibleFocusTemplate.MainPage"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
 <UserControl.Resources>
   <Style x:Key="StrongFocusIndicator" TargetType="Button">
...
     <Setter Property="Template">
       <Setter.Value>
         <ControlTemplate TargetType="Button">
...
             <VisualStateManager.VisualStateGroups>
               <VisualStateGroup x:Name="FocusStates">
                 <VisualState x:Name="Focused">
                   <Storyboard>
                     <DoubleAnimation Duration="0" To="1"
 Storyboard.TargetProperty="Opacity"
 Storyboard.TargetName="FocusVisualElement"/>
                     <DoubleAnimation Duration="0" To="0.5"
 Storyboard.TargetProperty="(UIElement.Opacity)"
 Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
                   </Storyboard>
                 </VisualState>
                 <VisualState x:Name="Unfocused"/>
               </VisualStateGroup>
             </VisualStateManager.VisualStateGroups>
...
             <Border x:Name="FocusVisualElement"
 IsHitTestVisible="false" Opacity="0"
 CornerRadius="2" BorderBrush="#D0FF0000"
 BorderThickness="4">
               <Rectangle x:Name="rectangle"
 IsHitTestVisible="false" Margin="2"
 Opacity="0" RadiusY="2" RadiusX="2"
 Fill="#A0FF0000"/>
             </Border>
          </ControlTemplate>
       </Setter.Value>
     </Setter>
   </Style>
 </UserControl.Resources>
 <StackPanel x:Name="LayoutRoot">
   <Button Width="275">Default button</Button>
   <Button Width="275"
 Style="{StaticResource StrongFocusIndicator}"
 >Button with re-templated focus visible indicator</Button>
 </StackPanel>
</UserControl>

The most interesting aspect of this example is the change made to the FocusVisualElement part. Here is the original (default template) FocusVisualElement:

<Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" 
 Opacity="0" IsHitTestVisible="false" />

Here is the changed FocusVisualElement:

<Border x:Name="FocusVisualElement" IsHitTestVisible="false"
 Opacity="0" CornerRadius="2"
 BorderBrush="#D0FF0000" BorderThickness="4">
 <Rectangle x:Name="rectangle" IsHitTestVisible="false"
 Margin="2" Opacity="0"
 RadiusY="2" RadiusX="2" Fill="#A0FF0000"/>
</Border>

The following images show how each of the two buttons (default and reskinned) appear when focused.

Default button focus

Reskinned button focus

This example is shown in operation in the working example of Visible Focus Template.

Resources

Tests

Procedure

Note that not all Silverlight applications necessarily will start with the keyboard focus being somewhere within the Silverlight content area for purpose of Step #2. It may be necessary to press TAB several times to traverse the browser's framing user interface. Also, within the browser's display area that displays the HTML document, there might also be other HTML elements that are keyboard focusable, which are representative of HTML that falls lexically before the <object> tag that instantiates the Silverlight plug-in. So it may also be necessary to press TAB several times until these HTML elements are traversed.

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Using a keyboard, tab to the element where focus characteristics are being examined.

  3. Check that the background, border, or other noticable visual indicator of the element changes color.

  4. Check that the changes in color for the background, border, or other noticable visual indicator are removed when the element loses focus.

Expected Results

#3 and #4 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL3: Controlling Silverlight MediaElement Audio Volume

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL3. Also see Silverlight Technology Notes.

Description

The objective of this technique is to adjust the volume for media that is played in Silverlight applications, as implemented through incorporating the Silverlight MediaElement object. By default, a MediaElement will start playing its media as soon as the UI loads completely AND the media source file is downloaded. For details, see SL24: Using AutoPlay to Keep Silverlight Media from Playing Automatically.

At any given time, a Silverlight MediaElement is associated with exactly one media source as specified by the Source property URI value. That source might be audio-only, or audio-video. The Volume property of MediaElement affects the audio playback volume of that particular source when it is playing. The Silverlight plug-in does not have a user option that adjusts the volume of ALL Silverlight applications as run within it, or a standardized user interface that is always present for all uses of MediaElement. Therefore it is the responsibility of Silverlight application authors to provide an adequate set of user interface controls, including volume adjustment, whenever the Silverlight application plays media that has an audio component.

Examples

Example 1: Providing a volume control and a Mute control as part of a set of user interface controls that go with a MediaElement

In addition to the Play Pause Stop controls, application authors can also provide a dedicated control that changes the Volume property of the MediaElement. The typical control for setting a discrete volume is Slider, because Slider is designed for input of discrete values from a range. Adjusting Volume with a data bound Slider changes the volume of any actively playing media, independent of the system volume or of any other audio source controlled by Silverlight. For Volume as set with the Slider, the Binding in XAML declares the interaction between the control and the MediaElement, without requiring an event handler. However, not all users will be able to interact quickly with a Slider, particularly if they are not using a mouse. To help these users, application authors should also include a "Mute" control. Rather than setting Volume to 0, application authors should instead set IsMuted to true. Note that Volume and IsMuted values are not directly related; if IsMuted is set to true, that does not set Volume to 0, nor does setting Volume to zero cause IsMuted to be set true.

<UserControl x:Class="MediaElementControls.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
   <Grid x:Name="LayoutRoot">
       <StackPanel>
           <MediaElement x:Name="media" Source="/xbox.wmv"
          Width="300" Height="300" 
          AutomationProperties.Name="Video of new Fable game for XBox"           
       />
           <Grid Name="UIControls">
               <Grid.ColumnDefinitions>
                   <ColumnDefinition Width="*" />
                   <ColumnDefinition Width="*" />
                   <ColumnDefinition Width="*"/>
               </Grid.ColumnDefinitions>
               <Grid.RowDefinitions>
                   <RowDefinition Height="*" />
                   <RowDefinition Height="Auto" />
                   <RowDefinition Height="20" />
               </Grid.RowDefinitions>
               <Button Click="StopMedia" 
    Grid.Column="0" Grid.Row="1" Content="Stop" />
               <Button Click="PauseMedia" 
    Grid.Column="1" Grid.Row="1" Content="Pause" />
               <Button Click="PlayMedia" 
    Grid.Column="2" Grid.Row="1" Content="Play" />
               <Button Click="MuteMedia" 
   Grid.Row="2" Grid.Column="0" Content="Mute" />
               <TextBlock Name="VolumeLabel" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right">Volume</TextBlock>
               <Slider Height="20"
           Value="{Binding Volume, Mode=TwoWay, ElementName=media}"
           Minimum="0" Maximum="1"
           Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2"
               AutomationProperties.LabeledBy="{Binding ElementName=VolumeLabel}"/>
           </Grid>
       </StackPanel>
   </Grid>
</UserControl>

The following is the C# logic.

 private void StopMedia(object sender, RoutedEventArgs e)
 {
     media.Stop();
 }
 private void PauseMedia(object sender, RoutedEventArgs e)
 {
     media.Pause();
 }
 private void PlayMedia(object sender, RoutedEventArgs e)
 {
     media.Play();
 }
 private void MuteMedia(object sender, RoutedEventArgs e)
 {
    Button target = sender as Button;
    // mute if not muted, unmute if already muted, in either case make sure the button content for text and accessibility info is updated
    if (!media.IsMuted)
    {
       media.IsMuted = true;
       target.Content = "Unmute";
    }
    else
    {
        media.IsMuted = false;
        target.Content = "Mute";
    }
 }

This example is shown in operation in the working example of Media Element Controls.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. It is expected that the application incorporates a MediaElement.

  2. Check that a control is available for controlling volume and that the Volume control controls the volume of the playing media, independently from system volume.

  3. Check that control is available for muting, and that the Mute control mutes the volume of the playing media, independently from system volume.

Expected Results

#2 OR #3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL4: Declaring Discrete Silverlight Objects to Specify Language Parts in the HTML DOM

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL4. Also see Silverlight Technology Notes.

Description

The objective of this technique is use the HTML Lang attribute on the object tag to describe each Silverlight plug-in instance on the HTML hosting page as a "part" that has a different language. Assistive technologies that use HTML Lang as a determinant of language of parts can thus treat all Silverlight content as using that HTML Lang-declared language.

Most assistive technologies that are capable of determining Language for Web content will use the HTML Lang tag value as the determinant of the language of the page. Assistive technologies would also use HTML Lang tag values for the language of parts. HTML Lang is not specifically reported in accessibility frameworks. Assistive technologies would typically access the HTML DOM to get this information. This technique specifically addresses this known situation regarding how ATs obtain Language information from HTML rather than from accessibility frameworks that otherwise report other aspects of HTML content.

In order to support different language parts that each contain Silverlight content, authors declare one Silverlight object tag per continuous language part region in the HTML. For example, the following HTML is a simplication of HTML markup for a page that contains two Silverlight content areas, the first declaring Lang as English (en), the second declaring Lang as German (de):

     <body>
       <object type="application/x-silverlight-2" lang="en">
       </object>
       <object type="application/x-silverlight-2" lang="de">
       </object>
     </body>
     

To support communication between different Silverlight plug-in instances that are hosted on the same HTML page, application authors can use various techniques, including the following

  • System.Windows.Messaging APIs: this is the simplest technique, and this is shown in Example 1

  • Using a shared business object, and exchanging information by having each Silverlight instance reference two-way data binding to that business object's properties.

  • Exchanging information through the HTML DOM and declaring properties of one or both instances as Scriptable by the DOM.

Silverlight runtime language determination

Regardless of how HTML Lang is declared on the defining object tags, many aspects of how Silverlight works with language and culture information at run time are not determined by HTML Lang, and are instead determined by the operating system and which culture that operating system is running. For more information, see Understanding Language/Culture Properties as Used by Silverlight Applications and Assistive Technologies.

Examples

Example 1: Two Silverlight object tags, each with different HTML Lang, to support a simple language-translator application as a Web page

The Visual Studio solution for this example has a total of 4 project components:

  • The Web project that declares the HTML or ASP page that shows the framework of how the two Silverlight object tags exist on a page. This is where the HTML Lang is actually set.

  • A project for the English user control, a simple TextBox.

  • A project for a German user control, also a simple TextBox.

  • A library with a static translation function

In this example, the English user control implements a LocalMessageSender, which sends asynchronous messages to the German user control. The German user control has a LocalMessageReceiver, which is set to listen as soon as the control is instantiated. When a message is received, the German control calls a function of the translation library, and displays translated text.

The following is the HTML page (some infrastructure and parameters omitted for clarity):

<html xmlns="http://www.w3.org/1999/xhtml" >
<body>

    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="25px" lang="en">
      <param name="source" value="ClientBin/SilverFish.xap"/>
    </object>

    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="25px" lang="de">
      <param name="source" value="ClientBin/SilverFish_DE.xap"/>
    </object>

</body>
</html>

The following is the XAML for the English user control:

<UserControl x:Class="SilverFish.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="20" 
>
   <Grid x:Name="LayoutRoot" Background="White">
       <TextBox AcceptsReturn="False" Language="en-us"
       Name="EnglishTranslationBox" 
       LostFocus="EnglishTranslationBox_LostFocus"/>
   </Grid>
</UserControl>

The following is the code-behind for the English user control:

   public partial class MainPage : UserControl
   {
       private LocalMessageSender messagesender;
       public MainPage()
       {
           InitializeComponent();
       }
       private void EnglishTranslationBox_LostFocus(object sender, RoutedEventArgs e)
       {
           messagesender = new LocalMessageSender("receiver");
           messagesender.SendAsync((sender as TextBox).Text);
       }
   }
   

The following is the code-behind for the German user control (the XAML is minimal; the main relevant point is that it contains a TextBox target named GermanTranslationBox). The code invokes the translation function found in a separate library. The translation function is not shown, it simply takes an English string and returns a German translation.

   public partial class MainPage : UserControl
   {
       public MainPage()
       {
           InitializeComponent();
           LocalMessageReceiver lmr = new LocalMessageReceiver("receiver");
           lmr.MessageReceived += new EventHandler<MessageReceivedEventArgs>(lmr_MessageReceived);
           try
           {
               lmr.Listen();
           }
           catch (ListenFailedException) {}
       }
       void lmr_MessageReceived(object sender, MessageReceivedEventArgs e)
       {
           if (e.Message!="") {
               String translated;
               translated = Translator.TranslateThat(e.Message);
               GermanTranslationBox.Text = translated;
               GermanTranslationBox.Focus();
           }
       }
   }

This example is shown in operation in the working example of SilverFish.

Resources

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references multiple Silverlight object tags, each with different HTML Lang values.

  2. Verify that language settings through HTML Lang on object tags are respected by assistive technologies that can use HTML Lang values for language of parts determination.

Expected Results

#2 gives expected results.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL5: Defining a Focusable Image Class for Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL5. Also see Silverlight Technology Notes.

Description

The objective of this technique is to wrap the Silverlight Image class inside a UI container class that is focusable. If the image is focusable, users who use the TAB sequence to navigate content while the assistive technology is active, and/or assistive technologies that construct navigation structures that are based on the TAB sequence, can both detect the image in navigation. The assistive technology can then associate alternative text for that image within the navigation structure, and report the information to the user.

Many existing assistive technologies do not construct initial navigation views that are derived from UI Automation information if it is coming from a non-focusable element in a Silverlight user interface. This is particularly true if the assistive technology is in a navigation mode that is specifically intended to help users enter information into a form or similar interactive interface element; an example of this situation is the Forms Mode of the JAWS screen reader.

Image is an example of a Silverlight element that is not focusable. This technique and the example therein are intended to circumvent the possible omission of a nonfocusable Silverlight Image element from certain navigation views in existing assistive technology implementations. The Silverlight Image is wrapped with a display/viewer control class that is focusable. This image-wrapping control is initially presented in assistive technology representations of a Silverlight user interface that use only focusable elements when constructing the assistive technology's representation of the application.

The image wrapper class uses the AutomationProperties.Name property to provide a short text alternative for the contained Image, so that the alternative text can be read or otherwise presented by assistive technologies. The Silverlight API AutomationProperties.Name directly sets Name in the UI Automation tree. The properties in the UI Automation tree are reported to assistive technologies, when the assistive technology implements behavior that acts as a UI Automation client. Name is one of the accessibility framework properties that most assistive technologies present in some way, for purposes of both name and value information, and setting Name is the common technique for exposing text alternatives for any other Control class (for example, for a button with an image, as shown in the technique SL18: Providing Text Equivalent for Nontext Silverlight Controls With AutomationProperties.Name).

This technique is intended for cases where application authors deliberately do not want a visible image caption for the image to be part of the user interface, and the image is a part of a larger interactive user interface control or page. Otherwise, if there is a visible caption, authors can use SL26: Using LabeledBy to Associate Labels and Targets in Silverlight.

Examples

The two examples are intended to be used together, if an application is both defining and consuming the focusable image control.

Example 1: Defining the FocusableImage XAML template and C# code behavior

Silverlight supports a control development model whereby the visual appearance of a control is largely defined in XAML, and the behavior of a control (such as its event handling and hookups to services) are implemented in a managed code language such as C#. The following is the XAML template, which includes a visual state that shows visually when the control is focused in UI.

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ImageEquivalent">
 <Style TargetType="local:FocusableImage">
   <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="local:FocusableImage">
        <Grid>
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="FocusStates">
              <VisualState x:Name="Focused">
                <Storyboard>
                  <ColorAnimation  
 Storyboard.TargetName="focusborder"
 Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
 Duration="0" To="Blue"/>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Unfocused"/>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <Border
            x:Name="focusborder"
            BorderThickness="4"
            BorderBrush="Transparent">
            <Image
             Margin="2" Opacity="10"
             Source="{TemplateBinding Source}"/>
         </Border>
       </Grid>
    </ControlTemplate>
    </Setter.Value>
   </Setter>
 </Style>
</ResourceDictionary>

The following is the C# class definition and logic. The logic includes invoking a default automation peer on creation, and loading the template as defined in the previous XAML example through the Silverlight "generic.xaml" resource convention for custom controls.

namespace ImageEquivalent
{
   public class FocusableImage : Control
   {
       protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
       {
           return new FrameworkElementAutomationPeer(this);
       }
       public FocusableImage()
       {
           this.DefaultStyleKey = typeof(FocusableImage);
       }
       public ImageSource Source
       {
           get { return (ImageSource)this.GetValue(SourceProperty); }
           set { this.SetValue(SourceProperty,value); }
       }
       public static DependencyProperty SourceProperty = DependencyProperty.Register(
         "Source",
         typeof(ImageSource),
         typeof(FocusableImage),
         null);
       Boolean _Focused;
       void ChangeState()
       {
           if (_Focused)
           {
               VisualStateManager.GoToState(this,"Focused",false);
           }
           else
           {
               VisualStateManager.GoToState(this,"Unfocused",false);
           }
       }
       protected override void OnGotFocus(RoutedEventArgs e)
       {
           base.OnGotFocus(e);
           this._Focused = true;
           ChangeState();
       }
       protected override void OnLostFocus(RoutedEventArgs e)
       {
           base.OnGotFocus(e);
           this._Focused = false;
           ChangeState();
       }
   }
}

This example is shown in operation in the working example of Focusable Image.

Example 2: Using the FocusableImage class in UI and applying AutomationProperties.Name

Now that the image is wrapped by a focusable control, you can instantiate an instance of the wrapper UI inside a Silverlight layout container, specify AutomationProperties.Name at the level of the wrapper control’s tag, and have that text serve as the alternative text for the referenced source image file.

   <StackPanel
   xmlns:local="clr-namespace:ImageEquivalent;assembly=FocusableImage"
   >
   <local:FocusableImage
     Height="300" Width="400
     AutomationProperties.Name="Diagram of secret lair"
     Source="/diagram_lair.png" />
   </StackPanel>

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Automation Tree

Procedure

  1. Open the test HTML page in a Silverlight-supported useragent host; to use UI Automation, use Microsoft Windows as platform.

  2. Use the tab sequence inside the Silverlight content area to focus the control.

  3. Using an accessibility framework verification tool, check that the string content is promoted as the default Name applied to the control.

Note: Accessibility framework verification tools typically show the entirety of an automation tree for a given application, and in fact will show the tree for all applications running on the Windows client machine. Focusing the control as in #2 is thus not strictly speaking necessary. However, manually focusing using the application interface is often a faster way to step into the automation tree as opposed to having to open an extensive series of nested nodes starting from the browser host application root. Whether this functionality exists depends on which accessibility framework verification tool is being used for testing.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.

Tests

Screen Reader

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. To use UI Automation, use Microsoft Windows as platform.

  2. Engage the screen reader. Move focus to the control (for example, use the tab sequence).

  3. Check that the Name applied to the image is read by the screen reader.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL6: Defining a UI Automation Peer for a Custom Silverlight Control

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL6. Also see Silverlight Technology Notes.

Description

The objective of this technique is to create an AutomationPeer class for a custom Silverlight control. The AutomationPeer exposes accessibility properties of the control in a way that abstracts the Silverlight technology specifics of the control model and maps information to UI Automation concepts, so that these properties can be consumed by the UI Automation accessibility framework.

The AutomationPeer concept is part of the overall architecture design of the UI Automation system. The peer represents a deliberate abstraction of the control, such that a client can obtain pattern-based information about the specific purpose and capability of a control without knowing its implementation-specific object model or having to resort to using a framework-specific object model API. Also, the peers run in a different process than the controls they represent, which has performance and security advantages. For more information on UI Automation architecture, see UI Automation Overview on MSDN.

Creating a custom Silverlight control is one way that Silverlight application authors can create user interface components either for their own application, or as a packaged redistributable that provides the control UI for third parties. Creating an automation peer for a custom control reports control-specific information to the UI Automation accessibility framework, and enables a custom control to participate in all of the same techniques involving UI Automation that can be used for a control that is distributed in the core Silverlight run time. Assistive technologies can use the UI Automation accessibility framework to discover the name and role of the user interface component, and can get and set values by accessing UI Automation patterns. UI Automation thus supports extensibility, while maintaining a discovery system for names, roles and values of UI components.

Control authors associate a peer with a class by implementing a method override for the class implementation. Control authors declare name and role through properties that are general to any UI Automation peer. Control authors expose the means to get and set values by choosing to support one or more patterns that are usually associated with a role. For example, a control in the role of "Button" would typically support an "Invoke" pattern. A consumer of UI Automation could check whether the pattern was supported and then call the pattern-based method Invoke, which would activate the button without any device input events being produced or required.

By convention, controls and their automation peers share a naming pattern. For example, if a control is named Spinner, its automation peer is named SpinnerPeer. However, the actual wiring for the class-peer association is made in the control code by overriding OnCreateAutomationPeer. Thus it is necessary to have access to the control code in order to associate a new peer class implementation with that control.

In addition to properties, automation peers can also expose methods as part of the implemented UI Automation control pattern. For example, a peer implementing the Value pattern can provide an implementation of the SetValue method. The SetValue method can be called by a UI Automation client in order to programmatically set the value of the owner control. The functionality exposed by the implementation of a control pattern can be accessed either by automation-based testing, or by assistive technologies.

Examples

Example 1: SimpleNumericUpDown control and its peer

The example implements a very simple Silverlight custom control named SimpleNumericUpDown. The control is a templateable control, meaning that the UI is defined in a XAML file that serves as the default UI, but any consumer of the control can change the visual appearance by applying a new template. Nevertheless, the basic accessibility characteristics of the control can be shaped by the control author, and can apply even for cases where the visible UI is noticably different. This separation between design-implementation and code-behavior is one reason for the peer-owner design in UI Automation. The majority of the example shows the C# code, including the following :

  • Associating the peer with the class.

  • Defining the peer, and basic information such as the class name.

  • Reporting which patterns the peer supports. In this case the peer supports a Value pattern.

Control definition class:

   public class SimpleNumericUpDown : Control
   {
       public SimpleNumericUpDown()
       {
           this.DefaultStyleKey = typeof(SimpleNumericUpDown);
       protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
       {
           return new SimpleNumericUpDownAutomationPeer(this);
       }
 // templating and event handlers omitted
       public static DependencyProperty NumericValueProperty = DependencyProperty.Register(
           "NumericValue",
           typeof(Int32),
           typeof(SimpleNumericUpDown),
           new PropertyMetadata(0)
           );
       public Int32 NumericValue
       {
           get { return (Int32)this.GetValue(NumericValueProperty); }
           set {this.SetValue(NumericValueProperty,value);}
       }
   }
   

Automation peer definition:

   public class SimpleNumericUpDownAutomationPeer : FrameworkElementAutomationPeer, IValueProvider
   {
       private SimpleNumericUpDown OwnerControl { get { return (SimpleNumericUpDown)Owner; } }
       public SimpleNumericUpDownAutomationPeer(SimpleNumericUpDown owner)
           : base(owner) {}
       //peer overrides
       protected override string GetClassNameCore()
       {
           return "SimpleNumericUpDown";
       }
       protected override AutomationControlType GetAutomationControlTypeCore()
       {
           return AutomationControlType.Spinner;
       }
       public override object GetPattern(PatternInterface patternInterface) {
           if (patternInterface == PatternInterface.Value)
           {
               return this;
           }
           return base.GetPattern(patternInterface);
       }
       // Value pattern implementation
       String IValueProvider.Value
       {
           get { return OwnerControl.NumericValue.ToString(); }
       }
       bool IValueProvider.IsReadOnly {get{return false;}}
       void IValueProvider.SetValue(string value)
       {
           OwnerControl.NumericValue = Convert.ToInt32(value);
       }

This example is shown in operation in the working example of Simple Numeric UpDown control.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. To see UI Automation, use Microsoft Windows as platform.

  2. Use a verification tool that is capable of showing the full automation tree, and an object’s UI Automation properties and patterns as part of the tree. (For example, use UIAVerify or Silverlight Spy; see Resources links.) Select the item in the automation tree that is accessing the relevant custom automation peer implementation.

  3. Examine the set of properties exposed in the tree. Check that name is reported by Name, that the class name is reported as ClassName, and that there is a role as reported by the value of ControlType.

  4. If the control is expected to report a value, check that the value is reported in the tree somehow. (Exactly which property reports the value varies depending on the control function and pattern; for more information, see Windows Automation API).

  5. Check whether a control pattern is reported in the tree. If a control pattern is reported, test the methods of that pattern using facilities in the verification tool. Verify that invoking the methods has changed the corresponding read only property values in the tree.

Expected Results

#3, #4, and #5 (if applicable) are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL7: Designing a Focused Visual State for Custom Silverlight Controls

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL7. Also see Silverlight Technology Notes.

Description

The objective of this technique is to build custom visual states for custom controls that include visible focus indicators in the templates and parts.

The default Silverlight core controls all indicate some type of visible focus indication, through their default templates. For more information on how Silverlight controls will generally supply a default visual focus indicator, see Focus Overview on MSDN.

Silverlight control skinning is enabled through a deliberate separation of visible user interface design and control logic in the Silverlight control model. Control authors expect that application authors might reskin their control. But control authors should provide an initial default set of states, templates, etc. so that application authors have a good baseline of functionality to compare with their customization. Defining visible focus states for all control parts is an example of such baseline functionality. In order to make the visual focus state customizable, the visual state should be associated with a name. Ideally that name should have a human-readable meaning that hints at its purpose, but the real reason for the name is that it connects the XAML-defined template (which control consumers can change) with the control logic defined by the control author (which control consumers cannot change). Also, the visual names and groups in the XAML should be attributed on the control class, to assist design tools. The best resource for general information about Silverlight control customization is Silverlight documentation on MSDN.

Component Parts

Some controls are created by assembling various component parts that are already defined as controls either by the Silverlight run time libraries or by third parties. That scenario is not really what this technique is about, because in that case the focus behavior is already defined by the component's template, and the control author can re-use that behavior as-is or reskin it but still through the same named state definition. This technique specifically addresses how to define a control where the interactive surface has mouse and keyboard handling defined at a lower level for the control as a whole. The actual focus region is defined by the control author in that case, and the focus indicator is also defined to match the behavior visually and functionally.

Design for Focus Indicators

The general design principles for visual focus indicators are that the indicators should apply a visual change to the focus region's exterior margin. A common pattern is to deliberately define the visuals for the control with a pre-existing blank margin for its layout slot; that way when the focus indicator is applied, the focus indicator can fill that margin.

The actual graphic for the visual focus indicator is typically a border or shaped frame of a solid color brush with at least 1 pixel line thickness. The color used for the border stands out visually from the underlying control background or other elements of the control. The contrast between brush for visual focus and the remainder of control should be a contrast difference that is visible to users who do not distinguish the hue of colors, but can distinguish the lightness/value. In many cases the border is rectangular, to go along with the control's layout slot. However, if the control's basic shape is a non-rectangular shape, sometimes the focus indicator is designed to make a border around that shape. An example of a default Silverlight control that is round and applies an exterior round border as a focus indicator is a RadioButton.

Most focus indicator designs change only the border and do not change the main area of the control. One reason for this is that changes to the main control are typically reserved for other interactive states that also have a visual indicator. Specifically, controls need a visual state that indicates that the mouse is over the control (this is termed either MouseOver or Hover state). Controls that support activation also have a visual state that provides feedback for activation. For example, the default Silverlight RepeatButton changes its Background gradient on the button field to be darker blue value when the mouse is over the button, and changes to an even darker value blue when the button is activated (either by clicking the mouse or by pressing SPACE or ENTER with keyboard focus on the RepeatButton). To see this behavior in a live sample, see RepeatButton sample on MSDN.

Logic for Focus Indicators

Typical logic is that the border to indicate focus is present in the default template design, but with an initial value of Visibility=Collapsed. Then, a visual state for focus is defined with a name that properly indicates its purpose as text (example: "Focused"). In addition, a state is needed that undoes whatever changes were applied for focus, once focus moves to another element (for example, "Unfocused"). For example, if the "Focused" state sets the value Visibility=Visible on some element, the "Unfocused" state sets that value to Collapsed again. Silverlight's visual state system also provides a way to group related states with a factoring name (for example, "FocusStates"). For more information on state names and state groups in Silverlight visual states, as well as learning how these states define a control contract that any control consumers should follow if they reskin that control, see Customizing the Appearance of an Existing Control by Using a ControlTemplate on MSDN.

The visual state system is designed to support visual transitions to states, and for that reason the visual state system is closely coupled with the Silverlight animation system. By animating the transition, the visual appearance changes over a time interval. Typically, if transitions are used, the time interval is short, one second or less. In the case of focus indicators, it is typical to not use transitions and to instead make a discrete change; otherwise, the state change might be interpreted by users as a lag in interface response from their system.

The states themselves are designed in XAML, but are loaded and unloaded through logic that the control author defines as part of their control code. The control author does this by handling the appropriate events that occur while the event scope applies to their control. For example, to apply the "Focused" state, the control author handles the GotFocus event. Rather than handle the event directly, the more common pattern is to override a virtual method that acts as a prewired event handler, OnGotFocus. The centralized logic for visual state changes is the method GoToState, with one of the parameters to pass representing the XAML name of the correct state to load from the XAML templates. Examples for all of the APIs discussed here are available in the MSDN topic Creating a New Control by Creating a ControlTemplate.

Focus in Silverlight

Focus in Silverlight is equivalent to the larger user interface and application concept of keyboard focus. The element that has focus is the element within the Silverlight object tree and programming model that has first chance to process the Silverlight key events. As a more tangible example that is user-centric, if a TextBox has keyboard focus, then when the user presses keys on the keyboard, the characters associated with the user's pressed keys (or possibly input that is enabled by an assistive technology that can substitute for key strokes) will appear in the TextBox. A user interface element in Silverlight can obtain keyboard focus in one of three ways:

  1. The user uses the Silverlight tab sequence to traverse into the Silverlight content and to focus a specific control.

  2. The Silverlight application's logic calls the Focus() method programmatically to force focus to a control.

  3. The user performs some other action, for example uses the mouse to click on a control. That control's specific logic handles the Silverlight input event and uses that event as stimulus to call Focus() on that control. The difference between this case and the above case is that the behavior is typically built-in to that control's runtime behavior, and does not require each application author to call Focus() in application code.

Examples

Example 1: Visible focus indicator as a style and state

The following is the XAML that defines the basic (normal) control template. This control is simple: it has a yellow circle graphic, which overlays a red circle edge when the control is focused. The circle edge is defined by the "FocusVisual" element in the composition, and is initially Visibility=Collapsed (the expected visual state prior to being focused).

<ResourceDictionary
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:FocusVisualCustomControl"
>
   <Style TargetType="local:SampleControl">
       <Setter Property="Template">
           <Setter.Value>
               <ControlTemplate TargetType="local:SampleControl">
                   <Grid x:Name="ControlRoot">
                       <Ellipse x:Name="CoinGraphic"
                         Fill="Orange"
                         Width="{TemplateBinding Width}"
                         Height="{TemplateBinding Height}"
                       />
                       <Ellipse x:Name="FocusVisual"
                         Visibility="Collapsed"
                         Stroke="Red"
                         StrokeThickness="1"
                         Width="{TemplateBinding FrameworkElement.Width}"
                         Height="{TemplateBinding FrameworkElement.Height}"
                       />
                   </Grid>
               </ControlTemplate>
           </Setter.Value>
       </Setter>
   </Style>
</ResourceDictionary>

The following is the specific visual state portion. Note how the visual state includes an ObjectAnimation with discrete keyframes for hard transition between Visible and Collapsed, targeting the element "FocusVisual" in the composition shown in the previous XAML.

                       <VisualStateManager.VisualStateGroups>
                           <VisualStateGroup x:Name="FocusStates">
                               <VisualState x:Name="Unfocused"/>
                               <VisualState x:Name="Focused">
                                   <Storyboard>
                                       <ObjectAnimationUsingKeyFrames
                                         Storyboard.TargetName="FocusVisual" 
                                         Storyboard.TargetProperty="Visibility" Duration="0">
                                           <DiscreteObjectKeyFrame KeyTime="0">
                                               <DiscreteObjectKeyFrame.Value>
                                                   <Visibility>Visible</Visibility>
                                               </DiscreteObjectKeyFrame.Value>
                                           </DiscreteObjectKeyFrame>
                                       </ObjectAnimationUsingKeyFrames>
                                   </Storyboard>
                               </VisualState>
                           </VisualStateGroup>
                       </VisualStateManager.VisualStateGroups>
                       

The following is control logic in the control class that responds to the focus-related events and switches visual states in response. In this particular example, "Unfocused" is a state without a definition. Switching to the definitionless state has the effect of reverting to the default state, which in the case of this design is intentional. Alternatively, authors could make specific template changes that revert any animation that applied to the focused state.

       protected override void OnGotFocus(RoutedEventArgs e)
       {
           base.OnGotFocus(e);
           VisualStateManager.GoToState(this, "Focused", false);
       }
       protected override void OnLostFocus(RoutedEventArgs e)
       {
           base.OnLostFocus(e);
           VisualStateManager.GoToState(this, "Unfocused", false);
       }

This example is shown in operation in the working example of Visual Focus Indicator.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Using a keyboard, tab to the element where focus characteristics are being examined.

  3. Check that the background, border, or other noticable visual indicator of the element changes color.

  4. Check that the changes in color for the background, border, or other noticable visual indicator are removed when the element loses focus.

Expected Results

#3 and #4 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL8: Displaying HelpText in Silverlight User Interfaces

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL8. Also see Silverlight Technology Notes.

Description

The objective of this technique is to provide a long text alternative that replaces content when a short text alternative is not sufficient for a given user, and the user specifically requests that the application should provide more context or more information through the application user interface. The technique could also apply for providing a long text alternative for a nontext object, for example for an image that contains a level of detail that is difficult to capture in a standard visible-in-UI image caption.

Silverlight supports a UI Automation property named HelpText, to connote its possible usage to provide imperative instructions for interactive elements. HelpText is not always forwarded to users by existing assistive technologies, which is an issue discussed in the technique SL19: Providing User Instructions With AutomationProperties.HelpText in Silverlight. Rather than relying on a particular assistive technology's support for enabling users to access the UIA HelpText, application authors can introduce user interface elements into their design that databind directly to the HelpText property, but where the interface element is not necessarily displayed by default. An interface update might be designed to occur if the application user specifically activates a "Get Help" action that is presented in the initial user interface.

This technique emphasises a "HelpText" model as a factoring practice. Silverlight application authors can use the HelpText as a data source that centralizes such information, because it already exists and has that intended purpose in accessibility frameworks. For example, the HelpText could be shown in a tooltip, a popup, a separate user interface element that is deliberately rendered in close proximity, etc. For accessibility support, a recommended display option for HelpText is to add or dynamically alter a Silverlight text element in the primary user interface. Silverlight supports an adaptive layout metaphor. Adding text to the runtime elements in the application generally causes an interface redraw, which in turn informs assistive technologies (through UIA properties and events) that content might have changed.

To set the UIA HelpText in Silverlight, you set the attached property AutomationProperties.HelpText. AutomationProperties.HelpText can be set in code, but is typically set in XAML that defines a Silverlight UI.

HelpText and Tooltip

The same information that is used for AutomationProperties.HelpText long text alternatives could also be useful to sighted users. In this case, the same text could be displayed in a Silverlight ToolTip control. The reason that application authors should use both AutomationProperties.HelpText AND Tooltip in conjunction is because the Tooltip information is not introduced into the runtime accessibility framework information set by UI Automation, because that information set does not anticipate the mouse action triggers that cause tooltips to display. In Silverlight programming, a useful technique for sharing the same resource is to combine the Silverlight data binding feature with the .NET Framework embedded resource feature. For more information on combining Silverlight data binding and resources for common string sources, see How to Make XAML Content Localizable.

Examples

Example 1: Displaying a long text alternative for an Image with XAML

Application authors can specify the AutomationProperties.HelpText attribute on the Image element. The value provided for the attribute should be a meaningful long text alternative for the image content. The value of AutomationProperties.HelpText should augment rather than duplicate any AutomationProperties.Name or an associated Label or LabeledBy caption. One or both of these is also typically specified to provide the basic (short-text) accessibility support for an image.

<StackPanel x:Name="imgContainer">
 <Image
   Height="400" Width="600"
   Source="/office.png"
   x:Name="imgOffice"
   AutomationProperties.HelpText=”The standard office layout
includes one corner desk unit in the corner farthest from the
door, and one file cabinet against the same wall as the door.”/>
 <sdk:Label x:Name="lblimgOffice" Target="{Binding ElementName=imgOffice}">Diagram of standard office layout</sdk:Label>
 <Button x:Name="HelpButton" Click="HelpButton_Click">Provide text-only alternative description of the previous image</Button>
</StackPanel>

The following event handler removes the Help button and replaces it in UI with a TextBox that displays the long text alternative.

       private void HelpButton_Click(object sender, RoutedEventArgs e)
       {
           imgContainer.Children.Remove(HelpButton);
           TextBox tb = new TextBox();
           tb.IsReadOnly=true;
           tb.Text = AutomationProperties.GetHelpText(imgOffice);
           imgContainer.Children.Add(tb);
           tb.Focus();
       }

Example 2: Using HelpText to augment existing form labels, to provide long text instructions

This example provides instructions for two form fields. The same text is also displayed for mouse users as a Tooltip and the AutomationProperties.HelpText string is used as a common source for both display options. In this example, the form submission does not perform client-side validation (although server-side validation following a data round trip might still exist, or validation could be added similar to the technique shown in SL35: Using the Validation and ValidationSummary APIs to Implement Client Side Forms Validation in Silverlight).

The following is the XAML UI:

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
   x:Class="HelpTextAndToolTip.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
       <Grid x:Name="LayoutRoot" Background="White" Margin="10">
           <Grid.RowDefinitions>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
           </Grid.RowDefinitions>
           <Grid.ColumnDefinitions>
               <ColumnDefinition Width="Auto"/>
               <ColumnDefinition Width="200"/>
               <ColumnDefinition Width="Auto"/>
           </Grid.ColumnDefinitions>
           <TextBlock Text="Form With Tooltips" FontSize="16" FontWeight="Bold"
     Grid.Column="1" HorizontalAlignment="Center" />
           <sdk:Label x:Name="NameLabel" Target="{Binding ElementName=NameTextBox}"
     Grid.Row="2" Margin="3"/>
           <TextBox x:Name="NameTextBox" 
     AutomationProperties.Name="{Binding Content, ElementName=NameLabel}"
     Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
     Grid.Column="1" Grid.Row="2" Margin="3"
                    AutomationProperties.HelpText="{Binding NameTextBoxToolTipString,Source={StaticResource TooltipStrings}}">
           <ToolTipService.ToolTip>
               <ToolTip Content="{Binding NameTextBoxToolTipString,Source={StaticResource TooltipStrings}}" />
           </ToolTipService.ToolTip>
           </TextBox>
           <sdk:Label x:Name="AgeLabel" Target="{Binding ElementName=AgeTextBox}"
     Grid.Row="3" Margin="3" HorizontalAlignment="Right"/>
           <TextBox x:Name="AgeTextBox" 
     AutomationProperties.Name="{Binding Content, ElementName=AgeLabel}" 
     Text="{Binding Age, Mode=TwoWay, UpdateSourceTrigger=Explicit}"  
     Grid.Column="1" Grid.Row="3" Margin="3"
    AutomationProperties.HelpText="{Binding AgeTextBoxToolTipString,Source={StaticResource TooltipStrings}}">
           <ToolTipService.ToolTip>
               <ToolTip Content="{Binding AgeTextBoxToolTipString,Source={StaticResource TooltipStrings}}" />
           </ToolTipService.ToolTip>
       </TextBox>
       <StackPanel Orientation="Horizontal">
           <Button x:Name="SubmitButton" Content="Submit" Click="SubmitButton_Click" Grid.Column="1" Grid.Row="4" Width="50" Margin="3" />
           <Button x:Name="HelpButton" Click="HelpButton_Click">Get Help</Button>
       </StackPanel>
       </Grid>
</UserControl>

The following is the resource definition in app.xaml:

       <ResourceDictionary>
           <resources:Resource1 x:Key="TooltipStrings"/>
       </ResourceDictionary>
       

The generated resource code that defines the "Resource1" class is not shown here because it is mostly infrastructure that is produced by a generation task in Visual Studio. For more information about embedded resources in Silverlight, see Resources Overview on MSDN. The resources here contain just two strings:

  • NameTextBoxToolTipString: Must be 10 characters or less. Required.

  • AgeTextBoxToolTipString Must be a value between 0 and 120. Required.

The following is the event handler code, which changes the interface.

       private void HelpButton_Click(object sender, RoutedEventArgs e)
       {
           AgeLabel.Content = AgeLabel.Content + ": " + AutomationProperties.GetHelpText(AgeTextBox);
           NameLabel.Content = NameLabel.Content + ": " + AutomationProperties.GetHelpText(NameTextBox);
           NameTextBox.Focus();
       }
       

Note the call to Focus() - this puts the screen reader focus on the first form element so that the added text can be read. The very same text source as used for the Tooltip is added programmatically to the existing Label controls.

After the Get Help button is clicked, the visual appearance of the application is modified:

Before activating Get Help

Image:BeforeTooltipForm.png

After activating Get Help

Image:AfterTooltipForm.png

This example is shown in operation in the working example of HelpText and Tooltip.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. To see UI Automation, use Microsoft Windows as platform.

  2. For a control where this technique is used to provide a long text alternative, verify that an identifiable and usable "Get Help" control is present in the initial user interface or assistive technology representation of that interface.

  3. Verify that activating the "Get Help" control changes the user interface, and the changed user interface now displays or reports long text alternatives that better address the user's information needs.

  4. If using a screen reader, verify that the long text alternative can be read aloud.

Expected Results

#2 and #3 are true. If testing with a screen reader, #4 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL9: Handling Key Events to Enable Keyboard Functionality in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL9. Also see Silverlight Technology Notes.

Description

The objective of this technique is to handle key events in a Silverlight application and enable application-specific keyboard functionality in a Silverlight application. The keyboard functionality might relate to a particular element of the Silverlight application user interface, or might be a handler for global key events within the application, such as an application-wide access key.

In Silverlight, application authors handle user input by attaching event handlers for input events. The input events are implemented on a class that is a base element in the Silverlight class hierarchy, such that all Silverlight UI elements can be the source of an input event if the user interacts with them. Typically, the event handler names are specified in XAML, although it is also possible to wire events in code. The implementation of the handlers for the Silverlight managed code programming model is always done in C# or Visual Basic code.

The most commonly used input events are the following:

  • KeyUp, KeyDown - these are the key events. Which key is pressed is determined by event parameters passed to the handler.

  • MouseEnter, MouseOver, MouseLeave

  • MouseLeftButtonDown, MouseLeftButtonUp, MouseRightButtonDown, MouseRightButtonUp

Other forms of input that Silverlight supports include touch devices (with mouse promotion for cases where the application runs on devices that do not have touch input modes) and a related inking mode. For any UI interaction that uses mouse input or these other input modes, Silverlight application authors can write a parallel key event handler to provide users the keyboard equivalent.

Also, the Silverlight event system and control model combine to enable behavior whereby a mouse event and a keyboard event can be treated as the same event and can be handled by a common event handler. Using this technique, Silverlight authors can facilitate keyboard functionality in custom controls or as override behavior to existing Silverlight-supplied controls, and provide equivalence for mouse events or events that are specific to other input devices. Silverlight authors can also use controls that already have a keyboard equivalence as a built-in behavior.

The parallel key event handler case, and the built-in behavior case, are each shown in one of the examples.

All input events report a specific source that is communicated to handler code as an event parameter, so that the application author can identify which element in their Silverlight UI was being interacted with, and the application can perform an action that is relevant to that user input. In the case of mouse events, the event source is the element that the mouse pointer is over at the time. In the case of key events, the event source is the element that has focus. The element that has focus is visually indicated so that the user knows which element they are interacting with (see SL2: Changing The Visual Focus Indicator in Silverlight). Assistive technologies often have parallel conventions whereby the user is made aware of which element is visually focused and is the current input scope presented by the assistive technology,

Silverlight core control built-in keyboard functionality

The following is a list of the Silverlight-supplied controls that have some level of key equivalence as a built-in behavior. In these cases, it is not necessary to add a specific Key event handler; you can handle the event and/or rely on the built-in key handling as listed.

  • Button (SPACE and ENTER) - raises Click event.

  • Other ButtonBase classes eg RepeatButton, HyperlinkButton (SPACE and ENTER) - raises Click event.

  • TextBox (ENTER, unless in a mode where the TextBox accepts multiple lines) - moves focus to next control, treated like a TAB

  • ListBox (various keys) - see OnKeyDown Method.

  • ComboBox (arrow keys ) - traverse list choices as control UI if popup area displayed.

  • RichTextBox (various keys ) - enable edit mode operations; see RichTextBox Overview.

  • Slider (arrow keys ) - increment/decrement values.

Browser hosts and keyboard events

Silverlight is hosted as a plug-in inside a browser host. The Silverlight run-time only receives the input events that the browser host forwards to hosted plug-ins through a browser-specific program access layer. Occasionally the browser host receives input that the browser host itself handles in some way, and does not forward the keyboard event. An example is that a Silverlight application hosted by an Internet Explorer browser host on Windows operating system cannot detect a press of the ALT key, because Internet Explorer processes this input and performs the action of bringing keyboard focus to the Internet Explorer menu bar. Silverlight authors might need to be aware of browser-specific input handling models and not rely on key events for keys that are essentially reserved for use by a browser host. For more information, see Keyboard Support.

Other event models

This technique specifically discusses event handling for the Silverlight managed programming model. However, Silverlight also supports parallel models for event handling, either through a Silverlight run-time feature or due to Silverlight's role as a plug-in within a script-capable browser host. For example, events from the HTML DOM can be handled by JavaScript at HTML scope for the overall Silverlight plug-in; this uses the browser host as script processor and the Silverlight run-time is not directly involved. Or, HTML DOM events can be handled through an HTML bridge that calls into Silverlight application code. These event models can potentially be used to provide keyboard equivalence, but it is generally more convenient to use the managed code model as described in this technique. For more information on other event models in Silverlight, see Events Overview for Silverlight.

Examples

Two examples are given. The first example is for the scenario of a Silverlight application author that is simply incorporating an existing control into their application design, and is taking advantage of mouse-keyboard equivalence that is already defined by certain Silverlight core controls. The second example is from the perspective of a control author, or at least that of a Silverlight application author that intends to encapsulate behavior in a custom Silverlight control and use it in their own application. For this second example, the control will handle the general Silverlight input event KeyUp, in order to check for input from key(s) that are designated to have a specific input meaning for that control.

Example 1: Built-in keyboard equivalence for core Silverlight controls

This example pertains to cases where the control that handles key events is focusable (through the tab sequence, etc.) and where an existing Silverlight control behavior provides the keyboard equivalence In this example, a Silverlight UI includes a Button element. For sighted users, or users that generally use the mouse to interact with UI, a typical way to interact with the button is to position the mouse pointer over the element, and click the left mouse button. However, the Button also supports a built-in key handling behavior, whereby either the SPACE or ENTER keys are treated as an equivalent action to clicking the button with a mouse. The requirement for this interaction is that the Button must have keyboard focus at the point in time that SPACE or ENTER are pressed. The Button might gain focus because the user pressed the TAB key to move through the tab sequence, or some equivalent action enabled by assistive technology. In terms of the programming experience, the Silverlight application author does not have to separately handle KeyDown for this case. Within the Button control built-in code, the special case of SPACE or ENTER keys pressed while a Button has focus invokes the button’s Click event. Then the Silverlight application author can simply handle Click without differentiating whether the input action was a mouse click or a keyboard equivalent. The following is the entire XAML UI.

<UserControl x:Class="BuiltInKeyEquivalence.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
   <Grid x:Name="LayoutRoot" Background="White" Loaded="LayoutRoot_Loaded">
       <Button Name="button1"
   AutomationProperties.Name="Equivalence test"
   Height="20" Width="150"
   Click="button1_Click">Click me, or press SPACE!</Button>
   </Grid>
</UserControl>

The following is the C# logic.

   private void button1_Click(object sender, RoutedEventArgs e)
   {
       MessageBox.Show("You clicked a button ... or maybe you hit the space bar ... or ENTER ... it's all the same to me.");
   }
   private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
   {
       System.Windows.Browser.HtmlPage.Plugin.Focus();
    }

This example is shown in operation in the working example of built-in keyboard equivalents.

Example 2: Keyboard events for a custom control, keyboard equivalence

In this example, a new Silverlight custom control named SimpleNumericUpDown uses a control template that includes two buttons. To provide keyboard equivalence for the buttons, an event handler is defined by the control class code. The event handler invokes the action in response to certain accelerator keys, where these actions are equivalent to clicking the button composition parts of the control with a mouse. The following is the default XAML template.

<ControlTemplate TargetType="local:SimpleNumericUpDown">
  <Border Background="{TemplateBinding Background}"
          BorderBrush="{TemplateBinding BorderBrush}"
          BorderThickness="{TemplateBinding BorderThickness}" Name="controlFrame">
      <Grid>
          <Grid.ColumnDefinitions>
              <ColumnDefinition Width="*"/>
              <ColumnDefinition Width="30"/>
          </Grid.ColumnDefinitions>
          <TextBox x:Name="valueBox" Text="{Binding NumericValue, RelativeSource={RelativeSource TemplatedParent}}"/>
          <StackPanel Grid.Column="1">
              <Button Name="minusButton">-</Button>
              <Button Name="plusButton">+</Button>
          </StackPanel>
      </Grid>
  </Border>
</ControlTemplate>

The following C# code shows the event handlers. Also, the code includes the event-wiring technique that is used whenever a Silverlight control author implements a templateable control. This technique enables the separation of UI appearance (which can be overridden) from the input event-handling behavior (which is implemented by the control author).

   public class SimpleNumericUpDown : Control
   {
       public SimpleNumericUpDown()
       {
           this.DefaultStyleKey = typeof(SimpleNumericUpDown);
       }
       
       public override void OnApplyTemplate()
       {
           base.OnApplyTemplate();
           Button plusButton = GetTemplateChild("plusButton") as Button;
           Button minusButton = GetTemplateChild("minusButton") as Button;
           Border controlFrame = GetTemplateChild("controlFrame") as Border;
           plusButton.Click += new RoutedEventHandler(Increment);
           minusButton.Click += new RoutedEventHandler(Decrement);
           controlFrame.KeyUp += new KeyEventHandler(Handle_Accelerators);
       }
       private void Increment(object sender, RoutedEventArgs e)
       {
           this.NumericValue += 1;
       }
       private void Decrement(object sender, RoutedEventArgs e)
       {
           this.NumericValue -= 1;
       }
       private void Handle_Accelerators(object sender, KeyEventArgs e)
       {
           switch (e.Key)
           {
               case (Key.Left):
                   this.NumericValue -= 1; 
                   e.Handled=true;
                   break;
               case (Key.Right):
                   this.NumericValue += 1; 
                   e.Handled=true;
                   break;
               default: break;
           }
       }
       public Int32 NumericValue //definition omitted in this example
   }

This example is shown in operation in the working example of custom keyboard events.

Resources

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Press TAB key to move keyboard focus to various element parts of the user interface.

  3. Verify that any user interface actions that exist for a given element part each have a keyboard equivalent.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL10: Implementing a Submit-Form Pattern in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL10. Also see Silverlight Technology Notes.

Description

The objective of this technique is to declare Silverlight user interface elements related to user input and use the Silverlight two-way data binding techniques to provide a Submit button and opt-in forms submission logic pattern for forms. The Submit button serves as the final deliberate step of a form submission scenario. Silverlight programming techniques do not provide a "Submit button as a distinct object. Rather, application authors design their user input workflow such that it is a single user action that initiates change of context that is related to a data input scenario. The key to doing this in Silverlight is to use a data binding mode that sets UpdateSourceTrigger of all individual databound fields in that form or transaction. For any data binding where the UpdateSourceTrigger is Explicit, no real-time change is made to the data, until the UpdateSource method is called on each of these bindings. The application-specific Submit button is connected to an event handler that calls UpdateSource on all of the databound UI elements that comprise that form.

Validation of data

The Submit button itself can also be the UI element that provides warnings, instructions, etc. in a way that assistive technologies can report to users, through the AutomationProperties techniques. Using a Submit model for Silverlight form input to databound data sources relies on a particular data binding mode. The Submit model can be used either along with client-side or server-side validation techniques. The example does not explicitly include either validation technique.

Examples

Example 1: Two form fields with Submit

In this example, the form fields correspond to a data object that implements a view model. Silverlight uses the view model and data annotations to generate some of its UI, notably the names of the fields are bound to the original view model names from the data. This example has a UI defined in XAML and logic defined in C#. The following is the XAML UI , which also includes the binding definitions. Note the Mode=TwoWay, UpdateSourceTrigger=Explicit attributes in the bindings. This is the binding mode to use for the Submit button scenario.

<UserControl x:Class="BasicSubmitButton.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
 <StackPanel x:Name="LayoutRoot" Background="White" Margin="10">
   <Grid>
   <Grid.RowDefinitions>
       <RowDefinition Height="Auto"/>
       <RowDefinition Height="Auto"/>
       <RowDefinition Height="Auto"/>
       <RowDefinition Height="Auto"/>
       <RowDefinition Height="Auto"/>
   </Grid.RowDefinitions>
   <Grid.ColumnDefinitions>
       <ColumnDefinition Width="Auto"/>
       <ColumnDefinition Width="200"/>
       <ColumnDefinition Width="Auto"/>
   </Grid.ColumnDefinitions>
   <TextBlock Text="Form Input" FontSize="16" FontWeight="Bold"
     Grid.Column="1" HorizontalAlignment="Center" />
       <sdk:Label x:Name="NameLabel" Grid.Row="2" Margin="3"
   HorizontalAlignment="Right"
   Target="{Binding ElementName=NameTextBox}"/>
   <TextBox x:Name="NameTextBox" 
     AutomationProperties.Name="{Binding Content, ElementName=NameLabel}"
     Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
     Grid.Column="1" Grid.Row="2" Margin="3" />
       <sdk:Label x:Name="AgeLabel" Grid.Row="3" Margin="3"
   HorizontalAlignment="Right"
   Target="{Binding ElementName=AgeTextBox}"/>
   <TextBox x:Name="AgeTextBox" 
     AutomationProperties.Name="{Binding Content, ElementName=AgeLabel}" 
     Text="{Binding Age, Mode=TwoWay, UpdateSourceTrigger=Explicit}"  
     Grid.Column="1" Grid.Row="3" Margin="3" />
   <Button x:Name="SubmitButton" Content="Submit" Click="SubmitButton_Click"
     Grid.Column="1" Grid.Row="4" Width="50" Margin="3"
   AutomationProperties.HelpText="Activate this button to submit form."/>
   </Grid>
 </StackPanel>
</UserControl>

The following is the C# logic for the page. Note the SubmitButton_Click handler. This implementation disables the Submit button (representative of a change of context, because now the form cannot be submitted again) and provides user feedback without performing any validation. The test file included in this technique sets up its data object as a purely client side entity and does no validation, so that no service/server is necessary to use the test file. Each element with a binding calls the UpdateSource method, such that the act of pressing the Submit button commits all the form's information all at once. A full implementation might replace this with a server side data object infrastructure. A full implementation might also provide a "Reset" or "Edit" button to enable form submission again if there were issues.

private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
   (sender as Button).IsEnabled = false;
   NameTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
   AgeTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
   TextBlock tb = new TextBlock();
   tb.Text="Thank you, your form information was submitted.";
   LayoutRoot.Children.Add(tb);
}

This example is shown in operation in the working example of Basic Submit Button.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. To test UI Automation based behavior such as reading AutomationProperties.HelpText, use Microsoft Windows as platform.

  2. Verify that the user interface design of the form includes a clearly indicated Submit button (a control that adequately communicates to users that activating it will cause input to be submitted and might cause a change of context).

  3. Provide values for the various input fields of the form, and verify that doing so does not in and of itself change the context.

  4. Verify that if change of context occurs at all, that action is delayed until after the Submit button is activated.

Expected Results

#2, #3, and #4 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL11: Pausing or Stopping A Decorative Silverlight Animation

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL11. Also see Silverlight Technology Notes.

Description

The objective of this technique is to associate a "Pause" or "Stop" action for a Silverlight animation with a user interface control. This enables a user to pause or stop an animation in Silverlight content.

The Silverlight animation system is generalized such that nearly any Silverlight property of type Double, Point or Color can be animated, or a property can cycle through discrete object values. Thus the possibilities for which properties in the user interface can be animated are quite broad. The general technique shown can be used to pause or stop any Silverlight animation, including those that are purely decorative.

Pause versus Stop

Silverlight has two discrete methods for animation control: a Pause method and a Stop method. The difference in behavior is that Pause uses whatever the last value was while the animation was still running, and holds that value permanenently (unless the animation is restarted). Stop sets the value to be whatever value existed before the animation was started. However, calling Stop on an animation often results in a behavior that looks like a "reset" to the user; this is particularly true if the animation is animating an element's position on screen. In many cases, what might be a conceptual "stop" for the user is better accomplished by a "permanent Pause" in the Silverlight animation API. Whether to call Pause or Stop is an aesthetic decision and application authors can experiment to see which behavior has the best appearance. If application authors choose to use Stop, authors can simply replace the call to .Pause() with a call to .Stop() for any code that is based on this technique's example.

Examples

Example 1: Pausing a decorative animation

The following is the XAML UI. The animated object and the animation behavior are both described in XAML, as is the control that users can activate to pause the animation.

<UserControl x:Class="PauseBouncyBall.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
 <UserControl.Resources>
   <Storyboard x:Key="anim" RepeatBehavior="Forever" >
       <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Ball"
          Storyboard.TargetProperty="(Canvas.Top)"
        FillBehavior="HoldEnd" AutoReverse="True">
               <EasingDoubleKeyFrame Value="100" KeyTime="00:00:01">
                   <EasingDoubleKeyFrame.EasingFunction>
                       <BounceEase Bounces="-1" EasingMode="EaseIn"/>
                   </EasingDoubleKeyFrame.EasingFunction>
               </EasingDoubleKeyFrame>
           </DoubleAnimationUsingKeyFrames>
   </Storyboard>
 </UserControl.Resources>
 <Canvas x:Name="LayoutRoot" Background="White" Height="600" Width="800">
   <Ellipse Name="Ball" Fill="Red" Width="20" Height="20" Canvas.Top="200">
       <Ellipse.RenderTransform>
           <TransformGroup>
               <TranslateTransform/>
           </TransformGroup>
       </Ellipse.RenderTransform>
   </Ellipse>
   <Button HorizontalAlignment="Left" Width="200" Click="Button_Click">Stop the bouncy ball please!</Button>
 </Canvas>
</UserControl>

The following is the C# logic. One function is the "page" constructor, which is what starts and loops the animation. The other function is the event handler for the UI control (a button). The event handler retrieves the animation definition from the page resources, and calls the Pause method on the animation.

       public MainPage()
       {
           InitializeComponent();
           (this.Resources["anim"] as Storyboard).Begin();
       }
       private void Button_Click(object sender, RoutedEventArgs e)
       {
           (this.Resources["anim"] as Storyboard).Pause();
       }

This example is shown in operation in the working example of Pause Bouncy Ball.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. For Silverlight content with moving, blinking, scrolling or auto-updating content that is the result of a running Silverlight animation:

  2. Check for a mechanism to stop the movement, blinking, scrolling or auto-updating.

  3. Check that the movement, blinking, scrolling or auto-updating stops when the mechanism is activated and does not restart by itself.

  4. For pause, check that the animation can be restarted using a start mechanism.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL12: Pausing, Stopping, or Playing Media in Silverlight MediaElements

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL12. Also see Silverlight Technology Notes.

Description

The objective of this technique is to create a control user interface for the Silverlight MediaElement object. The controls enable users to pause or stop the video to prevent the video images on the MediaElement surface from moving, and stop video-associated audio. These UI controls enable an interaction defined in code event handlers. Each handler calls one of the following MediaElement methods:

Note that by default, a MediaElement will start playing its media as soon as the UI loads completely AND the media source file is downloaded (or a certain buffer size is reached, in the case of streaming media). Use the AutoPlay property to change this default.

Examples

Example 1: Providing MediaElement controls in the UI

This example has a UI definition in XAML and interaction logic in C#.

<UserControl x:Class="MediaElementControls.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 >
  <Grid x:Name="LayoutRoot">
      <StackPanel>
          <MediaElement x:Name="media" Source="/xbox.wmv"
         Width="300" Height="300" 
         AutomationProperties.Name="Video of new Fable game for XBox"           
      />
          <Grid Name="UIControls">
              <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="*" />
                  <ColumnDefinition Width="*" />
                  <ColumnDefinition Width="*"/>
              </Grid.ColumnDefinitions>
              <Grid.RowDefinitions>
                  <RowDefinition Height="*" />
                  <RowDefinition Height="Auto" />
                  <RowDefinition Height="20" />
              </Grid.RowDefinitions>
              <Button Click="StopMedia" 
   Grid.Column="0" Grid.Row="1" Content="Stop" />
              <Button Click="PauseMedia" 
   Grid.Column="1" Grid.Row="1" Content="Pause" />
              <Button Click="PlayMedia" 
   Grid.Column="2" Grid.Row="1" Content="Play" />
              <Button Click="MuteMedia" 
  Grid.Row="2" Grid.Column="0" Content="Mute" />
              <TextBlock Name="VolumeLabel" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right">Volume</TextBlock>
              <Slider Height="20"
          Value="{Binding Volume, Mode=TwoWay, ElementName=media}"
          Minimum="0" Maximum="1"
          Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2"
              AutomationProperties.LabeledBy="{Binding ElementName=VolumeLabel}"/>
          </Grid>
      </StackPanel>
  </Grid>
</UserControl>

private void StopMedia(object sender, RoutedEventArgs e)
{
    media.Stop();
}
private void PauseMedia(object sender, RoutedEventArgs e)
{
    media.Pause();
}
private void PlayMedia(object sender, RoutedEventArgs e)
{
    media.Play();
}
private void MuteMedia(object sender, RoutedEventArgs e)
{
    Button target = sender as Button;
    // mute if not muted, unmute if already muted, in either case make sure the button content for text and accessibility info is updated
    if (!media.IsMuted)
    {
        media.IsMuted = true;
        target.Content = "Unmute";
    }
    else
    {
         media.IsMuted = false;
         target.Content = "Mute";
     }
}

This example is shown in operation in the working example of Media Element Controls.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. The application is expected to incorporate a MediaElement in the user interface.

  2. Check that interactive controls are available so that users can pause or stop the media.

  3. Check that when activated, the controls stop or pause the media.

Expected Results

#2 and #3 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL13: Providing A Style Switcher To Switch To High Contrast

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL13. Also see Silverlight Technology Notes.

Description

The objective of this technique is to incorporate high contrast color choices into a user interface visual design for Silverlight, by changing the values of styles or templates, or changing values of individual resources such as brushes or colors.

Silverlight styles and templates are produced in XAML. Silverlight event handlers (such as the ones that engage the style switch) are written in code, but are often wired through a method name reference in the XAML. For more information on how to use templates, styles and resources to change the appearance of Silverlight controls, see Control Customization topic on MSDN.

Silverlight provides a built-in property that can determine whether the hosting operating system is using a high contrast theme. This is a Boolean value only; Silverlight API cannot determine any further specifics about the theme choice, such as the colors being used or the contrast ratio between the colors. Querying this property at application startup is one possible trigger mechanism for applying high contrast themes to Silverlight content. Another mechanism is to expose a control (such as a button or text link) to the user, so that the user can engage high contrast for a Silverlight application's content by activating a control within the Silverlight application.

Silverlight Toolkit themes and System Colors

An extension to the Silverlight core deliverables known as the Silverlight Toolkit provides theming APIs and various themed styles for Silverlight controls, including the core controls. Most of these themes are intended for design purposes, but the Silverlight Toolkit also provides a System Colors theme. The System Colors theme aligns the Silverlight theme brushes or colors with those of the settings applied to the Microsoft Windows operating system display options. When the user switches the system themes to use a theme that is typically used for high contrast, the underlying system brushes are redefined. A Silverlight application that uses the System Colors theme also uses the now-redefined colors in its UI, and will effectively use the same High Contrast colors that are user-selected for all other display. How to use the Silverlight Toolkit system themes is not described in this technique. However, the Silverlight Toolkit theme system is a viable option for providing high contrast as well as other more aesthetics-oriented UI experiences. For more information about the Silverlight Toolkit, see Toolkit site. The themes feature of Silverlight Toolkit is best explained by Silverlight Toolkit release notes (from a Microsoft-related blog).

Real-time changes not supported

SystemParameters.HighContrast is an adequate trigger for cases where high contrast is already engaged before the Silverlight plugin is loaded into a host. However, a limitation of using SystemParameters.HighContrast as a trigger mechanism is that Silverlight does not detect the change if it happens after the Silverlight plugin is loaded by the host HTML. If Silverlight authors want to support real-time changes, they should provide a user-initiated control option for changing to high contrast in Silverlight UI rather than solely relying on SystemParameters.HighContrast.

Silverlight and CSS

Silverlight content does not use information that comes from a CSS style as applied to the hosting HTML page. Therefore, techniques as implemented by browser user agents and described by G148: Not specifying background color, not specifying text color, and not using technology features that change those defaults or G156: Using a technology that has commonly-available user agents that can change the foreground and background of blocks of text do not work for Silverlight content, and C29 does not directly apply. For example, the Internet Explorer settings under Options / Appearance do not affect the fonts or contrast in the Silverlight content area.

Examples

Example 1: Silverlight application designed with brush resources and template resources that enable a high contrast switch

The example "application" for illustration is just text, a button and border. The concepts shown in the example can scale to any complexity of UI, including to applications that have thousands of lines of XAML. Note that the visual appearance of the button is already using a high contrast theme choice for its default state, to assure that the control is visible to anyone that requires a high contrast theme to see parts of the user interface per G174. To keep the example simple, the visual states (behaviors) associated with mouse-over, click, etc. have not been restyled for high contrast. Only the base appearance is changed. The example also shows a technique of storing original theme information and restoring it in response to user request.

<UserControl x:Class="HighContrast.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d"
   d:DesignHeight="300" d:DesignWidth="400">
   <UserControl.Resources>
       <SolidColorBrush x:Key="ArtsyBrush1" Color="Salmon"/>
       <SolidColorBrush x:Key="ArtsyBrush2" Color="Bisque"/>
       <SolidColorBrush x:Key="ArtsyBrush3" Color="DarkSalmon"/>
       <SolidColorBrush x:Key="ArtsyBrush4" Color="Blue"/>
       <Color x:Key="ArtsyBrush1Restore">Salmon</Color>
       <Color x:Key="ArtsyBrush2Restore">Bisque</Color>
       <Color x:Key="ArtsyBrush3Restore">DarkSalmon</Color>
       <Color x:Key="ArtsyBrush4Restore">Blue</Color>
       <RadialGradientBrush x:Key="ArtsyGradient">
           <GradientStop Color="AliceBlue" Offset="0"/>
           <GradientStop Color="LightBlue" Offset="0.4"/>
           <GradientStop Color="#D00000EE" Offset="1"/>
       </RadialGradientBrush>
       <Style x:Key="ArtsyButton" TargetType="Button">
           <Setter Property="Template">
               <Setter.Value>
                   <ControlTemplate TargetType="Button">
                       <Border CornerRadius="4"
                          BorderBrush="{StaticResource ArtsyBrush4}" BorderThickness="4">
                           <Grid>
                               <Rectangle Fill="{StaticResource ArtsyGradient}"
                                 RadiusX="2" RadiusY="2"/>
                               <ContentPresenter Content="{TemplateBinding Content}"
                               ContentTemplate="{TemplateBinding ContentTemplate}"/>
                           </Grid>
                           
                       </Border>
                   </ControlTemplate>
               </Setter.Value>
           </Setter>
       </Style>
       <Style x:Key="HighConButton" TargetType="Button">
           <Setter Property="Control.Background" Value="White"/>
           <Setter Property="BorderBrush" Value="Black"/>
           <Setter Property="Foreground" Value="Black"/>
       </Style>
   </UserControl.Resources>
   <Border BorderBrush="{StaticResource ArtsyBrush1}" BorderThickness="4">
       <StackPanel x:Name="LayoutRoot" Background="{StaticResource ArtsyBrush2}">
           <TextBlock
             Foreground="{StaticResource ArtsyBrush3}">High contrast demo</TextBlock>
           <Button Name="Switcher" Click="Switcher_Click"
             Width="160" Style="{StaticResource HighConButton}">
              <TextBlock Text="Switch to high contrast"/>
           </Button>
           <Button Name="Switchback" Click="Switchback_Click"
             Width="160" Style="{StaticResource HighConButton}" IsEnabled="False">
               <TextBlock Text="Switch to regular theme"/>
           </Button>
       </StackPanel>
   </Border>
</UserControl>

The second listing is the C# code for the event handlers.

       private void Switcher_Click(object sender, RoutedEventArgs e)
       {
           ChangeToHighCon();
       }
       private void ChangeToHighCon()
       {
           (this.Resources["ArtsyBrush1"] as SolidColorBrush).Color = Colors.Black;
           (this.Resources["ArtsyBrush2"] as SolidColorBrush).Color = Colors.White;
           (this.Resources["ArtsyBrush3"] as SolidColorBrush).Color = Colors.Black;
           (this.Resources["ArtsyBrush4"] as SolidColorBrush).Color = Colors.Black;
           Switcher.IsEnabled = false;
           Switchback.IsEnabled = true;
       }
       private void RestoreRegularCon()
       {
           (this.Resources["ArtsyBrush1"] as SolidColorBrush).Color =
             (Color)this.Resources["ArtsyBrush1Restore"];
           (this.Resources["ArtsyBrush2"] as SolidColorBrush).Color =
             (Color)this.Resources["ArtsyBrush2Restore"];
           (this.Resources["ArtsyBrush3"] as SolidColorBrush).Color =
           (Color)this.Resources["ArtsyBrush3Restore"];
           (this.Resources["ArtsyBrush4"] as SolidColorBrush).Color =
             (Color)this.Resources["ArtsyBrush4Restore"];
           Switcher.IsEnabled = true;
           Switchback.IsEnabled = false;
       }
       private void Switchback_Click(object sender, RoutedEventArgs e)
       {
           RestoreRegularCon();
       }
   }

The following images show the original, and the applied high contrast settings.

Low contrast image with "switch to high contrast" button enabled

High contrast image with "switch to regular theme" button enabled

This example is shown in operation in the working example of High Contrast.

Example 2: Use SystemParameters.HighContrast to detect system high contrast settings at application startup

This example uses the same UI and style definitions as the previous example. The sole addition a case statement that is added to the primary page constructor of the UI (defined in C#). The added code is everything other than the InitializeComponent() call (which is part of Silverlight infrastructure). Note that the added code calls a user-defined function ChangeToHighCon(), which is the same function and behavior as shown in Example 1 for the user-initiated high contrast switch.

       public MainPage()
       {
           InitializeComponent();
           if (SystemParameters.HighContrast)
           {
               ChangeToHighCon();
           }
       }

Resources

Resources are for information purposes only, no endorsement implied.

Tests

UI option for style switching

Procedure

To test a Silverlight UI option for style switching (Example 1):

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Check for a control that indicates it will change the application's appearance to use a high-contrast theme.

  3. Activate the control. Check that the Silverlight application's user interface color themes change to an appearance that uses at least a 4.5:1 contrast ratio per Success Criterion 1.4.3 (Contrast (Minimum)).

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.

Tests

HighContrast API

Procedure

To test the HighContrast API (Example 2):

  1. Use operating system settings (such as Ctrl+LeftShift+PrtScn shortcut on Windows 7) to enter high contrast mode prior to opening the test page.

  2. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  3. Check that the Silverlight application's user interface color themes change to an appearance that uses at least a 4.5:1 contrast ratio per Success Criterion 1.4.3 (Contrast (Minimum)).

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.

Tests

UI option for enhanced contrast

Procedure

To test a Silverlight UI option for style switching for enhanced contrast:

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Check for a control that indicates it will change the application's appearance to use an enhanced contrast theme.

  3. Activate the control. Check that the Silverlight application's user interface color themes change to an appearance that uses at least a 7:1 contrast ratio per Success Criterion 1.4.6 Contrast (Enhanced).

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL14: Providing Custom Control Key Handling for Keyboard Functionality in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL14. Also see Silverlight Technology Notes.

Description

The objective of this technique is to implement built-in handling of key events in a custom control. If a custom control is correctly implemented, then any Silverlight applications that include the control can rely on the built-in key handling for some or all of the desired keyboard equivalence of a control's functionality.

Defining a custom control requires that the control author write a default template for the control and also the initialization logic, including the default implementations for built-in keyboard equivalence. Typically, control authors provide keyboard equivalence for any actions that can be activated by a mouse click on the control surface, and that are not already providing a keyboard equivalence through the implementation of a composite part.

All input events report a specific source that is communicated to handler code as an event parameter, so that the application author can identify which element in their Silverlight UI was being interacted with, and the application can perform an action that is relevant to that user input. In the case of mouse events, the event source is the element that the mouse pointer is over at the time. In the case of key events, the event source is the element that has focus. The element that has focus is visually indicated so that the user knows which element they are interacting with (see SL2: Changing The Visual Focus Indicator in Silverlight). Assistive technologies often have parallel conventions whereby the user is made aware of which element is visually focused and is the current input scope presented by the assistive technology.

Browser hosts and keyboard events

Silverlight is hosted as a plug-in inside a browser host. The Silverlight runtime only receives the input events that the browser host forwards to hosted plug-ins through a browser-specific program access layer. Occasionally the browser host receives input that the browser host itself handles in some way, and does not forward the keyboard event. An example is that a Silverlight application hosted by an Internet Explorer browser host on Windows operating system cannot detect a press of the ALT key, because Internet Explorer processes this input and performs the action of bringing keyboard focus to the Internet Explorer menu bar. Silverlight authors might need to be aware of browser-specific input handling models and not rely on key events for keys that are essentially reserved for use by a browser host. For more information, see Keyboard Support.

Application authors should choose keys that avoid browser conflicts, but still are a natural choice for an accelerator. Using the CTRL key as a modifier is a convention that is frequently used in existing Silverlight applications.

Informing users of which keys to use for keyboard equivalence

If a control supports user interaction, which key to use to engage the keyboard equivalent behavior is not always obvious. One way to inform users of the possible key options that a control supports is to author an AutomationProperties.HelpText value in the application UI that gives instructions such as "Press the plus key to increment value". This is up to the application author to do; the control definitions do not provide a means to set HelpText by default, because any display technique for end user help is potentially too application-specific to be encapsulated in control definitions. Application authors might also consider using tooltips, providing a menu framework that visually indicates the key associations (perhaps with the Windows key-underlined convention), providing a generalized application Help, or displaying plain text in the user interface.

The On* method pattern in Silverlight

Silverlight classes often have methods that follow the naming pattern On* where the star is a string that also identifies an event. These On* methods are prewired event handlers, defined as virtual methods so that subclasses can override them. A consumer of a control class can change or augment the default behavior associated with that event by overriding the method, and typically also calls the base implementation so that the base functionality is preserved. This principle is illustrated in Example 1 by the overrides of OnGotFocus and OnLostFocus. Controls that introduce new events should consider also exposing a virtual On* method that pairs with the event, so that consumers of the custom control can use the same pattern.

Examples

Example 1: KeyNumericUpDown Control That Handles Arrow Key Equivalence for + and - Buttons

This example implements a custom Silverlight control that displays an integer value, and can increment or decrement the integer value based on user actions. When a user interacts with the control, the user can click the "+" and "-" buttons that are component parts of the control. The "+" and "-" button parts are deliberately not in the Silverlight tab sequence, because this is intended to be a complete control, where only the control itself (and not its constituent parts) are focusable and are reported as an element to the accessibility framework. To provide keyboard equivalence, the control defines a KeyUp handler. The design of the control treats an Up Arrow key press as equivalent to activating the "+" button, and the Down Arrow key as equivalent to activating the "-" button. The control implementation reinforces this behavior by having the button Click event handlers and the cases of the KeyUp handler call the same underlying helper functions (Increment() and Decrement()).

Handling the + and - keys as alternate or additional keyboard equivalents for the actions is also possible (if that is desired, handler would check for Key.Add or Key.Subtract values).

The following is the XAML-defined control template for this control.

   <Style TargetType="local:KeysNumericUpDown">
       <Setter Property="BorderThickness" Value="1"/>
       <Setter Property="Height" Value="22"/>
       <Setter Property="BorderBrush">
           <Setter.Value>
               <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                   <GradientStop Color="#FFA3AEB9" Offset="0"/>
                   <GradientStop Color="#FF8399A9" Offset="0.375"/>
                   <GradientStop Color="#FF718597" Offset="0.375"/>
                   <GradientStop Color="#FF617584" Offset="1"/>
               </LinearGradientBrush>
           </Setter.Value>
       </Setter>
       <Setter Property="Template">
           <Setter.Value>
               <ControlTemplate TargetType="local:KeysNumericUpDown">
                   <Grid x:Name="CompositionRoot">
                       <Grid.ColumnDefinitions>
                           <ColumnDefinition/>
                           <ColumnDefinition/>
                       </Grid.ColumnDefinitions>
                       <TextBox x:Name="Text" IsTabStop="False" AcceptsReturn="False"
 BorderThickness="0" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}"
 FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}"
 FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" MinWidth="20"
 TextAlignment="Right" VerticalAlignment="Center"  TextWrapping="NoWrap" Text="{TemplateBinding Value}">
                               <TextBox.Style>
                                   <Style TargetType="TextBox">
                                       <Setter Property="Template">
                                           <Setter.Value>
                                               <ControlTemplate TargetType="TextBox">
                                                   <ScrollViewer x:Name="ContentElement" BorderThickness="0" Padding="0"/>
                                               </ControlTemplate>
                                           </Setter.Value>
                                       </Setter>
                                   </Style>
                               </TextBox.Style>
                           </TextBox>
                       <StackPanel Orientation="Vertical" Grid.Column="1">
                       <Button Width="18" Height="18" IsTabStop="False" x:Name="plusButton">+</Button>
                       <Button Width="18" Height="18" IsTabStop="False" x:Name="minusButton">-</Button>
                       </StackPanel>
                       <Border x:Name="FocusVisualElement" BorderBrush="#FF45D6FA" BorderThickness="{TemplateBinding BorderThickness}" 
                       CornerRadius="1,1,1,1" IsHitTestVisible="False" Opacity="0"/>
                   </Grid>
               </ControlTemplate>
           </Setter.Value>
       </Setter>
   </Style>
   

The following is the implementation of the control class. Overrides of the base class are omitted for clarity, as is automation support. Note the event wiring in OnApplyTemplate; this is a common pattern for custom control definitions.

   public class KeysNumericUpDown : UpDownBase<double>
   {
       Grid root;
       Button plusButton;
       Button minusButton;
       Border focusRect;
       public KeysNumericUpDown()
       {
           this.DefaultStyleKey = typeof(KeysNumericUpDown);
       }
       public override void OnApplyTemplate()
       {
           base.OnApplyTemplate();
           root = this.GetTemplateChild("CompositionRoot") as Grid;
           root.KeyUp += new KeyEventHandler(Handle_Accelerators);
           plusButton = this.GetTemplateChild("plusButton") as Button;
           minusButton = this.GetTemplateChild("minusButton") as Button;
           plusButton.Click += new RoutedEventHandler(plusButton_Click);
           minusButton.Click += new RoutedEventHandler(minusButton_Click);
           focusRect = this.GetTemplateChild("FocusVisualElement") as Border;
       }
       void plusButton_Click(object sender, EventArgs e)
       {
           Increment();
       }
       void minusButton_Click(object sender, EventArgs e)
       {
           Decrement();
       }
       private void Increment()
       {
           this.Value += 1;
       }
       private void Decrement()
       {
           this.Value -= 1;
       }
       private void Handle_Accelerators(object sender, KeyEventArgs e)
       {
           switch (e.Key)
           {
               case (Key.Up):
                   this.Value -= 1;
                   e.Handled = true;
                   break;
               case (Key.Down):
                   this.Value += 1;
                   e.Handled = true;
                   break;
               default: break;
           }
       }
       protected override void OnGotFocus(RoutedEventArgs e)
       {
           base.OnGotFocus(e);
           if (focusRect != null)
           {
               focusRect.Opacity = 1;
           }
       }
       protected override void OnLostFocus(RoutedEventArgs e)
       {
           base.OnLostFocus(e);
           focusRect.Opacity = 0;
       }
   }
   

When this control is included in application UI, the usage is very simple. Note that there are no key handlers on this instance; the necessary key handling to wire up the increment/decrement logic is already built-in to all instances of the control.

<local:KeysNumericUpDown Width="100" Height="45"/>

This example is shown in operation in the working example of Numeric Up / Down control.

Resources

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Press TAB key to move keyboard focus to various element parts of the user interface, and in particular to areas that are known to be custom control implementations.

  3. Check that custom key commands exist for all these user interface actions and that these key commands are made known to the user.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL15: Providing Keyboard Shortcuts that Work Across the Entire Silverlight Application

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL15. Also see Silverlight Technology Notes.

Description

The objective of this technique is to introduce key handling that exists at the application root level of a Silverlight application, rather than per-element key handling. Event handling at the application level as opposed to at the element level is one way to address key equivalence. The key events provide key equivalence for particular user interface elements that a user might otherwise interact with using a mouse. This technique is related to events in the Silverlight programming model, as opposed to in the HTML DOM.

Handling key events at the root level of an application rather than only on the element that was the "source" of a key event is possible because of a Silverlight programming model feature known as event routing. For more information on event routing and how it works, see Events Overview for Silverlight.

This technique demonstrates a "menu" approach to key handling and user interaction. This technique is presented as a companion to SL9: Handling Key Events to Enable Keyboard Functionality in Silverlight, which can be thought of as an "accelerator key/hotkey" approach. The "menu" approach towards keyboard equivalence is perhaps just as common as the "hotkey" approach. It is often simpler to document a menu's key equivalence in a user interface than it is to document key equivalents of particular regions of an application, or to communicate to users that where the current focus is placed is relevant to how keyboard keys are interpreted by the application, even if the key action is relevant to only one of the controls in an interface. If all keys are handled at the top level, the specific focused element is no longer relevant.

In order to originate a key event that Silverlight application code can detect, some element in the Silverlight application must have keyboard focus. One way to assure keyboard focus is to focus the Silverlight plug-in as a whole, as called from within an event handler for Application.Startup. This is shown in the examples.

If an application does handle keys at top level, care should be taken to not interfere with specific text entry control behavior, such as typing into a TextBox. To avoid interactions, the design of key equivalence at the top level of an application typically relies on combinations with key modifiers. The Control/CTRL key is a key that is often used for this purpose. Application authors should also be aware of the implications of browser hosts that might handle the key event at HTML DOM level without making that event available to the Silverlight programming surface. For more information on this concept, see "Keyboard Events and Browser Hosts" section of Keyboard Support Overview for Silverlight on MSDN.

Application authors are responsible for correctly documenting the accelerator keys that are pertinent for their application. There are a variety of techniques for documenting user interface actions that are not described here. One possible suggestion is to include a generalized "Help" button that appears early in the application's reading order, which is focusable and has an AutomationProperties.Name value available as the text content or equivalent. Such a button can be activated without knowing any of the application's accelerator keys, and the activation result could be a new text element that enumerates the possible keys. For example, the application could display a Silverlight Popup with the following content:

A screen shot of a sample Popup control that documents specific accelerator keys

Examples

Example 1: Key handling by application root UserControl

This example has only one interactive control for simplicity, but with two possible key combinations for that control being handled as actions. The purpose and explanation of the control is reported through a TextBlock that is associated with the labeled control through use of AutomationProperties.LabeledBy in XAML. The control being illustrated is MultiScaleImage, which supports a zoom-in metaphor for examining an image that redraws at increasingly fine resolutions. For more information on MultiScaleImage, see Deep Zoom on MSDN.

The following is the startup logic at application level that sends focus to Silverlight in the HTML DOM.

       private void Application_Startup(object sender, StartupEventArgs e)
       {
           this.RootVisual = new MainPage();
           //bring overall DOM focus to Silverlight area, so that keys are captured by Silverlight
           System.Windows.Browser.HtmlPage.Plugin.Focus();
       }
       

The following is XAML UI for the main page.

 <UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    x:Class="ApplicationLevelKeyHandling.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" KeyUp="UserControl_KeyUp">

    <StackPanel x:Name="LayoutRoot" Background="White">
        <Button Name="bInstructions" Click="bInstructions_Click">Get Help</Button>
        <Popup Name="p">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <TextBlock FontWeight="Bold">Key</TextBlock>
                <TextBlock FontWeight="Bold" Grid.Column="1">Action</TextBlock>
                <TextBlock Grid.Row="1">Ctrl + Alt + Plus</TextBlock>
                <TextBlock Grid.Row="1" Grid.Column="1">Zooms in on the image</TextBlock>
                <TextBlock Grid.Row="2">Ctrl + Alt + Minus</TextBlock>
                <TextBlock Grid.Row="2" Grid.Column="1">Zooms out of the image</TextBlock>
                <Button Grid.Row="3" Click="button1_Click">Close this Help</Button>
            </Grid>
        </Popup>
        <MultiScaleImage x:Name="deepZoomObject"
         Source="source/dzc_output.xml" 
         MouseLeftButtonDown="DeepZoomObject_MouseLeftButtonDown"
         MouseRightButtonDown="DeepZoomObject_MouseRightButtonDown"
         AutomationProperties.LabeledBy="{Binding ElementName=lblInstructions}"/>
    </StackPanel>
 </UserControl>

The following is the C# logic. Note how the key handlers and mouse handlers reference the same logic function.

        private void UserControl_KeyUp(object sender, KeyEventArgs e)
        {
            if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control &&
                (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt &&
                e.Key == Key.Add)
            {
                DZIn();
            }
            if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control &&
                (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt &&
                e.Key == Key.Subtract)
            {
                DZOut();
            }
        }
        private void DeepZoomObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DZIn();
        }
        private void DeepZoomObject_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            DZOut();
        }
        private void DZIn()
        {
            this.deepZoomObject.ZoomAboutLogicalPoint(3, .5, .5);
        }
        private void DZOut()
        {
            this.deepZoomObject.ZoomAboutLogicalPoint(.333, .5, .5);
        }
        private void bInstructions_Click(object sender, RoutedEventArgs e)
        {

            // Set where the popup will show up on the screen.
            p.VerticalOffset = 25;
            p.HorizontalOffset = 25;
            // Open the popup.
            p.IsOpen = true;
        }
        void button1_Click(object sender, RoutedEventArgs e)
        {
            // Close the popup.
            p.IsOpen = false;

        }

This example is shown in operation in the working example of Application Level Key Handling.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Verify that keyboard focus is somewhere within the Silverlight content area, and not elsewhere in the hosting HTML or hosting browser user interface. If necessary, use TAB key to traverse the overall HTML tab sequence until an interface element within Silverlight displays a visual focus indicator.

  3. Verify that the keys to be used as keyboard equivalent action triggers for the application as a whole are documented for users. For example, text or long text alternative documents key / key combinations and short descriptions of actions.

  4. Verify that pressing the application-specific keys results in the action as expected in the application.

  5. Move keyboard focus throughout other areas of the Silverlight application, and verify that the same keys continue to function application-wide.

Expected Results

#3, #4 and #5 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL16: Providing Script-Embedded Text Captions for MediaElement Content

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL16. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use text captioning that is embedded in the stream with media displayed in a Silverlight MediaElement, and present that text captioning in a separate Silverlight control or text element.

This particular technique uses scripting files with a TimelineMarkers collection that are embedded directly within the media file. When text captioning is embedded directly in the streams, synchonization of the scripting stream versus the video content stream is done automatically by the MediaElement component. Each time the MarkerReached event fires, that is an indication that a synch point in the video that corresponds to a script marker entry has been reached. Silverlight application authors can obtain the text from the relevant timeline marker entry through their event handler implementations, and can display captions in the user interface area where the text captions are displayed. Typical Silverlight controls that can be used for displaying text captions include TextBlock (nonfocusable), TextBox, or RichTextBox. A typical interface design would place the caption-display control in close proximity to the MediaElement control that is being captioned, for example might place the captions directly underneath the MediaElement "screen".

Script-embedded captions are captions that are stored directly in the media file as metadata, rather than as a separate file. For information about techniques for captions in separate files, see SL28: Using Separate Text-Format Text Captions for MediaElement Content.

Tools

Producing the media file with TimelineMarkers captions directly in embedded scripting can be accomplished using the Microsoft Expression Encoder tool. Online help for the procedure of encoding scripting with text captions in the stream are available in the offline Help file that installs with the Microsoft Expression 4 Encoder products. For more information, see Expression Encoder Pro Overview.

There is a public API for introducing Markers into a WMV file, as part of the Windows Media Format SDK. Using Expression Encoder is the way that the task of directly embedding TimelineMarkers is presented and taught in Microsoft's available instructional material on Silverlight. However, because the mechanism is public, it is possible that other tools exist or will exist that can also produce media with script-encoded TimelineMarkers.

Examples

Example 1: MediaElement handles MarkerReached, displays marker text in existing TextBox

This example has a UI definition in XAML and interaction logic in C#. The following is the basic UI in XAML. This example is deliberately simple and does not include AutomationProperties for identification or user instructions. The most relevant part of this example is that the Silverlight author declares a handler for the event MarkerReached. This event fires potentially hundreds of times, once for each caption in the stream. Each time the event fires, the event handler runs and adds the text to the dedicated TextBox in the user interface.

<UserControl x:Class="MediaTimelineMarkers.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
   <StackPanel x:Name="LayoutRoot" Background="White">
       <MediaElement MarkerReached="OnMarkerReached"
       HorizontalAlignment="Left"
       Source="/spacetime.wmv"
       Width="300" Height="200" />
       <ScrollViewer>
           <TextBox Name="captionText" Height="40"
           IsReadOnly="true" AcceptsReturn="true"/>
       </ScrollViewer>
   </StackPanel>
 </UserControl>

private void OnMarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
{
   captionText.Focus();
   captionText.SelectedText = e.Marker.Text.ToString() + "\n";
}

This example is shown in operation in the working example of Media Timeline Markers.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. The application plays media that is expected to have text captioning.

  2. Check that a text area in the user interface shows captions for the media.

Expected Results

# 2 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL17: Providing Static Alternative Content for Silverlight Media Playing in a MediaElement

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL17. Also see Silverlight Technology Notes.

Description

The objective of this technique is to replace a Silverlight MediaElement with static alternative non-media content that is not time-based. The static alternative content replaces the media in the same or a nearby user interface region of the Silverlight application.

A Silverlight application user interface can be adjusted at run time by removing elements from the visual tree, and adding new elements to the visual tree. In this case, the user interface is designed to provide a control that the user activates to display the static alternative content, which is often a control that displays text, or a text element.

Examples

Example 1: MediaElement playing audio, replace with transcript

This example has a UI definition in XAML and interaction logic in C#. In this case the MediaElement has no visual representation itself and is 0x0 size because it plays audio only. As a simple placeholder, this example displays the text "Library of Congress Audio" to represent the media element as something visible in the UI. In addition to Play/Stop controls, this interface includes a Display Transcript button. Activating the button displays static text that represents the transcript of the audio. The following is the basic UI in XAML.

<UserControl x:Class="ReplaceAudioWithTranscriptText.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:sys="clr-namespace:System;assembly=mscorlib">
   <UserControl.Resources>
       <sys:String x:Key="transSpeakerName">Matt Raymond: </sys:String>
       <sys:String x:Key="transText">This is Matt Raymond at the Library of Congress.
Each year thousands of book lovers of all ages visit the nation's capital to celebrate the joys 
of reading and lifelong literacy, at the Library of Congress National Book Festival. 
For the first time in the festival's nine year history, President Barack Obama and 
First Lady Michelle Obama will serve as honorary chairs of this free event. </sys:String>
   </UserControl.Resources>
   <StackPanel x:Name="LayoutRoot" Background="White" >
       <TextBlock FontSize="30" Foreground="Blue">Library of Congress Audio</TextBlock>
       <MediaElement Source="/locintro.wma" AutoPlay="False" Name="player" Height="0" />
       <StackPanel Orientation="Horizontal" Name="ControlBar">
           <Button Name="Play" Click="Play_Click">Play</Button>
           <Button Name="Stop" Click="Stop_Click">Stop</Button>
           <Button Name="TextAlt" Click="TextAlt_Click">Display Transcript</Button>
       </StackPanel>
   </StackPanel>
</UserControl>

The following is the C# logic.

   public partial class MainPage : UserControl
   {
       RichTextBox rtb;
       bool transDisplayed=false;
       public MainPage()
       {
           InitializeComponent();
           rtb = new RichTextBox();
           rtb.IsReadOnly = true;
           Paragraph p = new Paragraph();
           Run speakerName = new Run();
           speakerName.Text = this.Resources["transSpeakerName"] as String;
           speakerName.FontWeight = FontWeights.Bold;
           Run transText = new Run();
           transText.Text = this.Resources["transText"] as String;
           p.Inlines.Add(speakerName);
           p.Inlines.Add(transText);
           rtb.Blocks.Add(p);
       }
       private void Play_Click(object sender, RoutedEventArgs e)
       {
           player.Play();
           Play.IsEnabled = false;
       }
       private void Stop_Click(object sender, RoutedEventArgs e)
       {
           player.Stop();
           Play.IsEnabled = true;
       }
       private void TextAlt_Click(object sender, RoutedEventArgs e)
       {
           Panel parent = (player.Parent as Panel);
           if (!transDisplayed)
           {
               DisplayTranscript();
               (sender as Button).Content = "Hide Transcript";
               transDisplayed = true;
           }
           else
           {
               parent.Children.Remove(rtb);
               (sender as Button).Content = "Display Transcript";
               transDisplayed = false;
           }
       }
       private void DisplayTranscript()
       {
           Panel parent = (player.Parent as Panel);
           parent.Children.Add(rtb);
       }

This example is shown in operation in the working example of Replace Audio With Transcript.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. That application has audio-only media content and is expected to supply a text alternative, or has media that is expected to be replaced entirely with a transcript or similar text alternative.

  2. Check for a control that indicates that activating it will supply static alternative content for the media. Activate the control.

  3. Verify that the media control is replaced with alternate content, and that assistive technologies represent the change to the user interface.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL18: Providing Text Equivalent for Nontext Silverlight Controls With AutomationProperties.Name

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL18. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the Silverlight AutomationProperties.Name property to provide a short text alternative for controls that do not otherwise contain text. The text is intended to provide human-readable identifiers and short-descriptions or user instructions for accessibility frameworks, which can then be reported to assistive technologies.

"Control" in this technique refers to any element that is based on the Silverlight Control class, and is keyboard-focusable either by user action or calling focus to the control programmatically. The non-text control in question might be something like a button that communicates information using only an icon or image. For example, a triangle image rotated 90 degrees clockwise is commonly used in many user interfaces to indicate a "Play" button control. This "Play" icon mimics interface metaphors from many non-software consumer products, and is often presented in a user interface without any nearby visible text information that explains the purpose of the control. Another example is a "thumbnail" metaphor where a small image serves as a control that can be activated, and where the action results in the display of a larger version of the same image, or enters an editing mode that loads the same image.

For cases of controls such as buttons that invoke actions, the text alternative also identifies link purpose.

In Silverlight, a text-only identifier for any control can be set specifically as AutomationProperties.Name on the parent control. Silverlight control compositing techniques enable either per-control images that are specified by the application author, or a general-purpose image/icon for a control that is part of the control's template and displays that way by default. The Silverlight API AutomationProperties.Name directly sets Name in the UI Automation tree. The properties in the UI Automation tree are reported to assistive technologies, when the assistive technology implements behavior that acts as a UI Automation client (or as an MSAA client, which relies on the UIA-MSAA bridge).

Examples

Example 1: Applying a text alternative for an icon Button with XAML

Application authors can specify the AutomationProperties.Name attribute on the Button element, and leave accessibility information for the composited Image content unspecified. It is the button and its action that is relevant to users, not the non-interactive Image component. The value provided for AutomationProperties.Name is a meaningful text alternative for the action conveyed by the button's icon/image, but where the functionality is conceptually embodied in the button and not its images or other constituent parts in compositing or visual design.

 <Button
   Height="20" Width="50"
   AutomationProperties.Name="Pause Media">
   <Image Height="12" Width="12" Source="/icon_pause.png"/>
 </Button>

This example is shown in operation in the working example of Button Text Alternative.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Accessibility framework view

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Use a verification tool that is capable of showing the full accessibility framework tree, and an object’s "Name" text alternative as part of the tree. Verify that all interactive elements such as buttons without visible text provide a human-readable text identifier "Name" in the automation tree.

Expected Results

#2 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.

Tests

Screen Reader

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Engage the screen reader. Press TAB to traverse the tab sequence inside the Silverlight content area to focus to a composite control that has no visible text, but has an AutomationProperties.Name applied.

  3. Check that the "Name" as applied to the control instance, along with the class name of the named control, is read by the screen reader.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL19: Providing User Instructions With AutomationProperties.HelpText in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL19. Also see Silverlight Technology Notes.

Description

The objective of this technique is to provide a long text alternative that serves the same purpose and presents the same information as the original non-text content when a short text alternative is not sufficient, and to show the practice of storing that information in a dedicated property of the Silverlight-supported UI Automation support system. The technique can also be used on text controls (such as TextBox), for cases where the control text itself does not provide enough context to suggest an appropriate user action.

The relevant UI Automation property is named HelpText, to connote its possible usage to provide imperative instructions for interactive elements. However, the same property can instead be used for long text alternatives for nontext objects. The Silverlight API AutomationProperties.HelpText directly sets HelpText in the UI Automation tree. The properties in the UI Automation tree are reported to assistive technologies, when the assistive technology implements behavior that acts as a UI Automation client.

AutomationProperties.HelpText can be set in code, but is most typically set as an attribute in XAML that defines a Silverlight UI.

The same information as is present in AutomationProperties.HelpText could also be useful to sighted users. In this case, the same text could be displayed in a Silverlight ToolTip control. The reason that application authors should use both AutomationProperties.HelpText AND Tooltip in conjunction is because the Tooltip information is not introduced into the runtime accessibility framework information set. This is because a tooltip is transient and not conventionally focusable. In Silverlight programming, a useful technique for sharing the same resource is to combine the Silverlight data binding feature with the .NET Framework embedded resource feature. For more information on combining Silverlight data binding and resources for common string sources, see How to Make XAML Content Localizable.

Examples

Example 1: Applying a long text alternative for an Image with XAML

To introduce the necessary information to Silverlight XAML for an application UI definition, specify the AutomationProperties.HelpText attribute on the Image element. The value provided for the attribute is a meaningful long text alternative for the image content. The value of AutomationProperties.HelpText should augment rather than duplicate AutomationProperties.Name, which is also typically specified to provide accessibility support for an image.

 <Image
   Height="400" Width="600"
   Source="/office.png"
   AutomationProperties.Name="Diagram of standard office layout"
   AutomationProperties.HelpText=”The standard office layout
includes one corner desk unit in the corner farthest from the
door, and one file cabinet against the same wall as the door.”/>

Example 2: Using HelpText as form instructions

This example provides instructions for two form fields by using both Tooltip and AutomationProperties.HelpText. The strings used for these purposes are shared to both methodologies by defining the strings as resources and binding to them. In this example, the form submission does not perform client-side validation (although server-side validation following a data round trip might still exist).

The following is the XAML UI:

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
   x:Class="HelpTextAndToolTip.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
       <Grid x:Name="LayoutRoot" Background="White" Margin="10">
           <Grid.RowDefinitions>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
           </Grid.RowDefinitions>
           <Grid.ColumnDefinitions>
               <ColumnDefinition Width="Auto"/>
               <ColumnDefinition Width="200"/>
               <ColumnDefinition Width="Auto"/>
           </Grid.ColumnDefinitions>
           <TextBlock Text="Form With Tooltips" FontSize="16" FontWeight="Bold"
     Grid.Column="1" HorizontalAlignment="Center" />
           <sdk:Label x:Name="NameLabel" Target="{Binding ElementName=NameTextBox}"
     Grid.Row="2" Margin="3"/>
           <TextBox x:Name="NameTextBox" 
     AutomationProperties.Name="{Binding Content, ElementName=NameLabel}"
     Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
     Grid.Column="1" Grid.Row="2" Margin="3"
     AutomationProperties.HelpText="{Binding
       NameTextBoxToolTipString,Source={StaticResource TooltipStrings}}">
           <ToolTipService.ToolTip>
               <ToolTip Content="{Binding NameTextBoxToolTipString,Source={StaticResource TooltipStrings}}" />
           </ToolTipService.ToolTip>
           </TextBox>
           <sdk:Label x:Name="AgeLabel" Target="{Binding ElementName=AgeTextBox}"
     Grid.Row="3" Margin="3" HorizontalAlignment="Right"/>
           <TextBox x:Name="AgeTextBox" 
     AutomationProperties.Name="{Binding Content, ElementName=AgeLabel}" 
     Text="{Binding Age, Mode=TwoWay, UpdateSourceTrigger=Explicit}"  
     Grid.Column="1" Grid.Row="3" Margin="3"
    AutomationProperties.HelpText="{Binding AgeTextBoxToolTipString,Source={StaticResource TooltipStrings}}">
           <ToolTipService.ToolTip>
               <ToolTip Content="{Binding AgeTextBoxToolTipString,Source={StaticResource TooltipStrings}}" />
           </ToolTipService.ToolTip>
       </TextBox>
           <Button x:Name="SubmitButton" Content="Submit" Click="SubmitButton_Click"
             Grid.Column="1" Grid.Row="4" Width="50" Margin="3" />
       </Grid>
</UserControl>

The following is the resource definition in app.xaml:

       <ResourceDictionary>
           <resources:Resource1 x:Key="TooltipStrings"/>
       </ResourceDictionary>
       

The generated resource code that defines the "Resource1" class is not shown here because it is mostly infrastructure that is produced by a generation task in Visual Studio. For more information about embedded resources in Silverlight, see Resources Overview on MSDN. The resources here contain just two strings, each of which would typically be defined in a Visual Studio .resx file. Resources in a .resx file can be localized or changed separately from code by the appropriate localization toolsets for Microsoft localization/development.

  • NameTextBoxToolTipString: Must be 10 characters or less. Required.

  • AgeTextBoxToolTipString Must be a value between 0 and 120. Required.

These examples are shown in operation in the working example of Automation Properties Help Text and working example of HelpText and ToolTip.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. To see UI Automation, use Microsoft Windows as platform.

  2. Use a verification tool that is capable of showing the full automation tree, and an object’s long text alternative as part of the tree. (For example, use UIAVerify or Silverlight Spy; see Resources links.)

  3. Focus an element that is known to have a long text alternative. Check that the AutomationProperties.HelpText as applied to individual UI elements appears as the HelpText or acc_Help value in the automation tree.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL20: Relying on Silverlight AutomationPeer Behavior to Set AutomationProperties.Name

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL20. Also see Silverlight Technology Notes.

Description

The objective of this technique is to illustrate how in certain cases, the Silverlight automation peer system can provide an accessibility framework Name based on any simple text strings that are also presented in the visible user interface as control content.

The applicability of this technique to SC 1.3.1 is that once promoted, the Name becomes the primary information item that describes the user interface element to accessibiity frameworks and assistive technologies, and the information is thus immune to any further applications of the Silverlight style system that might change the appearance of the visual text equivalent (styled with color, uses italic font for rendering basis, etc.)

The applicability of this technique to SC 4.1.2 is that the default peer promotion behavior provides the Name component of Name, Role, Value. This is related to the description of the term label in SC4.1.2.

A default behavior for generating Name for accessibility frameworks is possible for certain peers of content controls. The content controls that might support a default automation peer behavior include:

  • TextBlock

  • ButtonBase derived classes that do not change the GetNameCore implementation. This includes the Button class. In order for the default promotion to work, the Content of the button must be set as a plain string or must contain only a TextBlock; any compositing such as wrapping in a Border or other container will disable the default promotion.

  • Any other ContentControl derived class where the Content property contains either TextBlock or a text-content-only ButtonBase implementation as sole content.

In these cases the string that sets either Content (for ContentControl and ButtonBase) or Text (for TextBlock) is promoted as the AutomationProperties.Name for the control in UI Automation, without any further attribution. The properties in the UI Automation tree are reported to accessibility frameworks (UI Automation, and MSAA through the bridge). The accessibility frameworks reports this information to assistive technology clients.

Relying on default automation peer behavior is the preferred Silverlight technique for supplying the accessibility framework "Name" information, so long as the default peer promotion actually does produce a usable name. Using default behavior is preferred because re-using the strings that are already used in the general visual presentation is less likely to result in accessibility-specific strings being forgotten by the application author, or get decoupled from visible UI in a revision process.

For cases where there is control compositing in a control rather than simple text, the automation peer typically cannot provide a default simple string, and it may be the application author's responsibility to set AutomationProperties.Name explicitly as an attribute in XAML, or as a property in runtime code. For details, see SL30: Using Silverlight Control Compositing and AutomationProperties.Name.

Test-based methodology

In order to use this technique effectively, application authors are expected to be following a test-based methodology towards verifying what information their application is reporting to any pertinent accessibility framework. Useful tools for this purpose include SilverlightSpy and UIAVerify. Application authors might examine their running Silverlight application on a test machine where the accessibility framework test viewers are also active. Initially, the application author might view the application at a point in the application development cycle that is prior to any effort devoted to specifically adding accessibility-related information to the application. Silverlight applications might be in this state because the initial user interface design was done in a visually oriented design tool such as Microsoft Expression Blend. Using the test-based methodology, application authors might note that certain accessibility framework properties are already populated, as a result of the mechanisms that are described in this technique. However, it is rare that ALL of the necessary accessibility information for an application can be obtained entirely from the built-in default behaviors of the automation peers. At this point, the application author may have to apply additional Silverlight techniques that provide accessibility framework information, for example SL30: Using Silverlight Control Compositing and AutomationProperties.Name.

Examples

Example 1: Button is composed with direct text content only

The following example shows XAML UI only. Logic is not shown, but would typically be added by referencing a Click handler from the XAML.

 <Button Height="20" Width="200">Fire photon torpedoes!</Button>

The following illustration shows the UIAVerify tree view of this simple interface. Note that the internal string "Fire photon torpedoes!" is being peer-forwarded. This is verified by the Properties view on the right side: the Name property value is "Fire Photon Torpedoes", even though no programmatic Name property or AutomationProperties.Name has been applied to that button that would otherwise have supplied an acccessibility framework "Name".

UIAVerify tree view

This example is shown in operation in the working example of Simple Peer Forwarding.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. To use UI AUtomation, use Windows as the platform.

  2. Use a verification tool that is capable of showing the full automation tree, and an object’s name text alternative as part of the tree. (For example, use UIAVerify or Silverlight Spy; see Resources links.)

  3. Check that any element where default automation peer promotion is expected is supplying a default Name in the automation tree.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL21: Replacing A Silverlight Timed Animation With a Nonanimated Element

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL21. Also see Silverlight Technology Notes.

Description

The objective of this technique is to replace a timed Silverlight animation with a non-timed user interface element that presents equivalent information. This is useful in cases where the Silverlight animation is a timed animation that may contain information that the user wants to see without a time limit, such as crawling text in a text area. The animated version of information in the user interface element can instead be swapped out for an equivalent static element.

The Silverlight animation system is generalized such that nearly any Silverlight property of type Double, Point or Color can be animated, or a property can cycle through discrete object values. Thus the possibilities for which properties in the user interface can be animated are quite broad. The general technique shown can be used to stop any animation.

Examples

Example 1: Stopping an animation that is scrolling text, replacing the animation with a full text alternative

This example has a UI definition in XAML and interaction logic in C#. The following is the basic UI in XAML.

<UserControl x:Class="StopAnimation.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
   <UserControl.Resources>
       <ImageBrush x:Key="Stars" ImageSource="/stars.jpg" Stretch="Fill"/>
       <Storyboard x:Key="crawl">
           <DoubleAnimation From="700" To="-100" Duration="0:0:20"
             Storyboard.TargetName="crawltext" Storyboard.TargetProperty="(Canvas.Top)"/> 
       </Storyboard>
       <sys:String x:Key="crawlText">
           Episode IV, A NEW HOPE It is a period of civil war. Rebel spaceships, striking from a hidden base, 
           have won their first victory against the evil Galactic Empire. During the battle, Rebel spies managed 
           to steal secret plans to the Empire’s ultimate weapon, the DEATH STAR, an armored space station with 
           enough power to destroy an entire planet. Pursued by the Empire’s sinister agents, Princess Leia 
           races home aboard her starship, custodian of the stolen plans that can save her people and restore 
           freedom to the galaxy….
       </sys:String>
   </UserControl.Resources>
   <StackPanel x:Name="LayoutRoot"
   Background="{StaticResource Stars}"
   Height="600" Width="800">
       <Button Width="200"
   Click="Button_Click">Stop crawling text, display fixed text</Button>
       <Canvas Name="CrawlPanel" Width="605" Height="595" >
           <Canvas.Projection>
               <PlaneProjection RotationX="-75"/>
           </Canvas.Projection>
           <Canvas.Clip>
               <RectangleGeometry Rect="0 0 600 600"/>
           </Canvas.Clip>
           <TextBlock Text="{StaticResource crawlText}"
   TextWrapping="Wrap" FontSize="20"
   Width="300" Canvas.Left="150" Name="crawltext"
   Foreground="Goldenrod"/>
       </Canvas>
   </StackPanel>
</UserControl>

The following is the C# logic. In this example, the animation starts automatically. When the user activates the control (the Button), the event handler stops the animation, removes the animated element from the visual tree, and replaces it with a fixed text element that presents all text at once. Because it is a TextBox, assistive technologies could identify the newly introduced text element and present it, for example read the text in a screen reader.

       public MainPage()
       {
           InitializeComponent();
           (this.Resources["crawl"] as Storyboard).Begin();
       }
       private void Button_Click(object sender, RoutedEventArgs e)
       {
           (this.Resources["crawl"] as Storyboard).Stop();
           LayoutRoot.Children.Remove(CrawlPanel);
           TextBox tb = new TextBox();
           tb.IsReadOnly = true;
           tb.FontSize = 30;
           tb.TextWrapping = TextWrapping.Wrap;
           tb.Text = (string)this.Resources["crawlText"];
           LayoutRoot.Children.Add(tb);
       }

This example is shown in operation in the working example of Stop Text Animation.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. For a Silverlight application that has a time limit on interaction due to an animated user interface element:

  2. Check for a mechanism to stop the time limit on interaction.

  3. When the mechanism is activated, check that the element that is animated and resulting in a time limit is removed, and the time-limited element is replaced with static content that is equivalent and does not have a time limit.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL22: Supporting Browser Zoom in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

  • Silverlight content in a user agent host that supports browser zoom

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL22. Also see Silverlight Technology Notes.

Description

The objective of this technique is to support or anticipate existing browser zoom features effectively when users interact with the Silverlight application. This technique explains how the Silverlight content area reacts to the browser zoom feature implemented by some user agent hosts. Silverlight content and layout properties are based on physical screen pixel measurements. When the browser zoom is engaged, Silverlight content scales correctly for the zoom factor, and uses the same zoom factor as any surrounding HTML content.

Browser zoom is relevant for accessibility and Silverlight because it is likely to be the zoom /scaling feature enabled by the browser host that Web technology users are the most familiar with as a technique for increasing the text size in Web content.

Legacy behavior in Silverlight version 2

Built-in support for browser zoom was introduced as a feature in Silverlight version 3. Older documents on the Web might describe techniques that were relevant for Silverlight version 2, where dealing with browser zoom required JavaScript handling of the Resized event, and developers manually applied a ScaleTransform to Silverlight content to scale it up. Silverlight has a "quirks mode" that detects existing handlers that might still use the older techniques. Built-in zoom not active in these cases, so that applications can avoid doubling or otherwise mishandling the user agent's zooming behavior.

Deliberately disabling browser zoom in Silverlight applications

Silverlight also provides the ability to disable the built-in browser zoom handling and rendering behavior. This is sometimes done in order to suppress some of the aliasing and distortion artifacts that host-level scaling can introduce, particularly for video content or certain uses of text. In these cases, application authors might consider other Silverlight techniques for scaling the user interface, perhaps specifically only for the text elements on a page. When an application disables the built-in zoom behavior and rendering for Silverlight content, the browser still retains its zoom settings, and that setting applies to other content outside of Silverlight such as the hosting HTML.

Examples

Example 1: Verifying browser zoom, and checking the zoom factor

This example has a UI defined in XAML and logic defined in C#. The UI shows the zoom factor, and also demonstrates what happens when built-in browser zoom handling is deliberately disabled. Note that the zooming factor as reported by the API is still retained even when Silverlight built-in zoom scaling is disabled deliberately. The following is the XAML UI:

<UserControl x:Class="BrowserZoom.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
   <StackPanel x:Name="LayoutRoot" Background="White">
       <TextBlock>Some text you can zoom.</TextBlock>
       <Button Click="Button_Click">Toggle built-in zoom handling</Button>
       <StackPanel Orientation="Horizontal">
           <Button Click="Button_Click_1">Query current zoom factor</Button>
           <TextBox IsReadOnly="true" Name="zoomf"
   Text="{Binding Path=reportZoom}"/>
       </StackPanel>
   </StackPanel>
</UserControl>

The following is the C# logic:

   public partial class MainPage : UserControl
   {
       public MainPage()
       {
           InitializeComponent();
       }
       private void Button_Click(object sender, RoutedEventArgs e)
       {
           if (!Application.Current.Host.Settings.EnableAutoZoom == false) {
           Application.Current.Host.Settings.EnableAutoZoom = false;
           }
           else
           {
               Application.Current.Host.Settings.EnableAutoZoom = true;
           }
       }
       private void Button_Click_1(object sender, RoutedEventArgs e)
       {
           zoomf.Text = Application.Current.Host.Content.ZoomFactor.ToString();
       }
   }

This example is shown in operation in the working example of Browser Zoom.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. The browser being used for the test must support a browser zoom feature, and the feature must be turned on as a user preference.

  2. Verify that the Silverlight application enables auto zoom (no Silverlight application-specific code or markup has set EnableAutoZoom API to false).

  3. Test the zooming feature of the user agent. Verify that browser zoom factors apply to the Silverlight content.

Expected Results

#2 and #3 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL23: Using A Style Switcher to Increase Font Size of Silverlight Text Elements

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL23. Also see Silverlight Technology Notes.

Description

The objective of this technique is to define style switching logic for Silverlight. In particular, the intent is to use the style switcher to change the font size of text elements. This technique could be used only for specific elements, or could also be applied to the entire Silverlight content area and all text elements therein (including elements such as TextBlock that are technically not controls). Examples are provided for these two cases.

The property to style or otherwise change is the FontSize property. Primarily, this is done using the API Control.FontSize, but developers can also use similar properties on other objects that do not derive from Control (examples: TextBlock; DataGridTextColumn).

Silverlight uses a style system whereby many properties that affect UI appearance can be referred to and changed through a style resource. The style resource overrides the default code implementation and the default XAML template as provided by the Silverlight core implementation(or a third party control author). A style enables an application author to make a one-to-many change to property values in an efficient and reversible way, and also to group multiple related property changes as one unit of logic. Styles can be applied explicitly by referencing them by name, or implicitly by associating a style with a class (which then targets all instances of that class). This is analogous to how CSS can either define styles globally for tags or uniquely for classids and names.

Silverlight styles are always written in XAML. Silverlight event handlers are most often written in code (there are related techniques that can react to states with event associations, defined in pure XAML, but the specific style switching technique is most straightforward in code).

Using this technique versus relying on browser zoom

Silverlight supports browser zoom when viewed in browser hosts that support a browser zoom feature. Specifically, Silverlight scales content within its content area when the user engages browser zoom, based on the browser zoom factor. However, not all browser hosts that Silverlight supports have a browser zoom feature, and/or users might choose not to use browser zoom. This technique presents an alternative technique for font scaling in cases when relying on browser zoom is not viable as a technique. Applications might use HTML DOM based logic to determine the user agent string of the browser host, and use that as a determinant of whether the user has browser zoom available as an option. If no browser zoom feature exists for that user and their user agent, that user could be served a version of the Silverlight application that presents a UI and logic for sizing the fonts using the Silverlight API, as described in this technique.

For more information about Silverlight and browser zoom, see the technique SL22: Supporting Browser Zoom in Silverlight.

Sizing by percent

Generally, sizing Silverlight FontSize values by percentages is not recommended. Sizing by percentage produces non-integer font size values, which in turn produce aliasing artifacts. The Silverlight rendering routines for text work best when dealing with integer numbers. The entire Silverlight rendering system is based on pixel measurements. In particular, the behavior for text rendering produces optimized font shaping and subpixel rendering for text areas, and this behavior is based on the assumption that font unit measurements will be provided by applications using whole pixel values.

Units for font sizing in Silverlight

Font sizing in Silverlight is always specified by a unit measure of pixels. Other unit measures such as ems or points that come from a migrated UI definition in XAML would need to be unit-converted to all use a purely numeric value, such that attribute values in XAML do not not include unit identifier suffixes such as "px", "pt", "em", or "cm". This note is most relevant if the application author is porting or migrating a Windows Presentation Framework (WPF) application to Silverlight, or is using a XAML-emitting design tool that is producing general XAML UI definitions and not targeting a specific framework.

Examples

Example 1: Style applied to all text elements within a RichTextBox container

Variations of this example could be employed to offer more choices. For example, multiple style switchers could be provided that gave three or more fontsize choices.

<UserControl x:Class="StyleSwitcherFontSize.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
   <UserControl.Resources>
       <Style x:Key="BiggerRTBFonts" TargetType="RichTextBox">
           <Setter Property="FontSize" Value="24"/>
       </Style>
   </UserControl.Resources>

   <StackPanel x:Name="LayoutRoot" Background="White">
       <Button Click="Button_Click">Super size fonts!</Button>
       <Button Name="Undo" Click="Undo_Click">Make those big fonts stop!</Button>
       <RichTextBox IsReadOnly="True" Name="rtb1">
           <RichTextBox.Blocks>
               <Paragraph>Various test text</Paragraph>
               <Paragraph>
                   <Bold>Some bold test text</Bold></Paragraph>
               <Paragraph>
                   <Italic>Some italic</Italic>
               </Paragraph>
               <Paragraph FontFamily="Times New Roman">A different font, why not?</Paragraph>
           </RichTextBox.Blocks>
       </RichTextBox>
   </StackPanel>
</UserControl>

The second listing is the C# code for the event handler . Note that all it does is change a style property, using a value that keys into the .Resources collection from XAML where the Style is defined. Another event handler nulls out the style and returns values to defaults.

private void Button_Click(object sender, RoutedEventArgs e)
{
  rtb1.Style = this.Resources["BiggerRTBFonts"] as Style;
}
private void Undo_Click(object sender, RoutedEventArgs e)
{
   rtb1.Style = null;
}

The following images show the original, and the applied style.

Screen shot with standard fonts and a button to enlarge

Screen shot with enlarged fonts after activating button to enlarge

This example is shown in operation in the working example of Style Switcher Font Size.

Example 2: Font size increase applied to all text content by applying at UserControl level, and by percent increase logic

This example uses the inheritance characteristics of the FontSize property that is available to all Silverlight controls. Rather than using a style, this example uses a HoldEnd animation, to take advantage of the "By" behavior of the animation system that can increment an existing value by 2 (pixels) rather than replacing the value with a fixed pixel value.

The following is the XAML UI:

<UserControl x:Class="StyleSwitcherFontSize.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Name="rootcontrol">
   <UserControl.Resources>
       <Storyboard x:Key="BySize">
           <DoubleAnimation Storyboard.TargetName="rootcontrol" Storyboard.TargetProperty="FontSize" By="2" FillBehavior="HoldEnd" Duration="0"/>
       </Storyboard>
   </UserControl.Resources>
   <StackPanel x:Name="LayoutRoot" Background="White">
       <Button Click="Button_Click">Super size fonts!</Button>
       <Button Name="Undo" Click="Undo_Click">Make those big fonts stop!</Button>
       <TextBox Text="Various test text"/>
       <TextBox FontWeight="Bold" Text="Some bold test text"/>
       <TextBox FontStyle="Italic" Text="Some italic"/>
       <TextBox FontFamily="Times New Roman" Text="A different font, why not?"/>
   </StackPanel>
</UserControl>

The following are the C# event handlers.

private void Button_Click(object sender, RoutedEventArgs e)
{
   (this.Resources["BySize"] as Storyboard).Begin();
}
private void Undo_Click(object sender, RoutedEventArgs e)
{
   (this.Resources["BySize"] as Storyboard).Stop();
}

This example is shown in operation in the working example of By Animation Font Size.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Verify that the application provides a control that can increase font size.

  3. Activate the control, and check that the font sizes increase.

Expected Results

#2 and #3 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL24: Using AutoPlay to Keep Silverlight Media from Playing Automatically

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL24. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the AutoPlay property of MediaElement object, which prevents the MediaElement from playing its media source automatically.

By default the value of AutoPlay is true, which causes any media that is the Source of the MediaElement to play as soon as either the entire source file is loaded (for nonstreaming media) or an initial buffer is loaded (for streaming media). To prevent the possible accessibility issues, developers can instead specifically set AutoPlay to false, so that the user always controls whether the media plays. This technique would thus be used in combination with providing user interface controls that go along with the MediaElement, and that enable the user to control the media. In particular, the user interface controls enable the media to play, pause or stop, with event wiring for those controls associated with the Play, Pause or Stop methods of the MediaElement object.

Examples

Example 1: Setting AutoPlay to false, and providing the typical MediaElement controls in the UI

This example has a UI definition in XAML and interaction logic in C#.

The following is the basic UI in XAML. Note the AutoPlay="false" setting.

<UserControl x:Class="MediaElementControlsAutoPlay.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
   <Grid x:Name="LayoutRoot">
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="*" />
           <ColumnDefinition Width="*" />
           <ColumnDefinition Width="*"/>
       </Grid.ColumnDefinitions>
       <Grid.RowDefinitions>
           <RowDefinition Height="*" />
           <RowDefinition Height="Auto" />
       </Grid.RowDefinitions>
       <MediaElement x:Name="media" Source="/xbox.wmv"
          Width="300" Height="300" 
          Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
          AutoPlay="False"
          AutomationProperties.Name="Video of new Fable game for XBox"           
       />
       <Button Click="StopMedia" 
    Grid.Column="0" Grid.Row="1" Content="Stop" />
       <Button Click="PauseMedia" 
    Grid.Column="1" Grid.Row="1" Content="Pause" />
       <Button Click="PlayMedia" 
    Grid.Column="2" Grid.Row="1" Content="Play" />
   </Grid>
</UserControl>

The following is the C# logic.

 private void StopMedia(object sender, RoutedEventArgs e)
 {
     media.Stop();
 }
 private void PauseMedia(object sender, RoutedEventArgs e)
 {
     media.Pause();
 }
 private void PlayMedia(object sender, RoutedEventArgs e)
 {
     media.Play();
 }
 

This example is shown in operation in the working example of Media Element Controls with AutoPlay False.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. The application is expected to use a MediaElement object to play prerecorded media.

  2. Check that the media does not play automatically as soon as the application loads and displays. Rather, the user is presented with a user interface that can start the media per the user's action.

Expected Results

#2 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL25: Using Controls and Programmatic Focus to Bypass Blocks of Content in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL25. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the combination of Silverlight control activation and programmatic focus to enable the user to skip regions of content in a Silverlight application user interface.

The control that the user activates should clearly indicate that its purpose is to skip content, so that the resulting programmatic focus shift is not interpreted as an undesired change of context.

The object to call focus to (the receiver of focus after the user-initiated action is triggered) has to be a Control in the Silverlight programming model. This is because the Focus method must be called on the target, and therefore the target must inherit the Control class. So, an application author might call focus to a read-only TextBox, or perhaps a RichTextBox, depending on the purpose of the Silverlight application and its user interface design. You can also focus a UserControl, for cases where the area to call focus to represents a custom control implementation.

Setting TabIndex (not recommended)

Silverlight provides a TabIndex attribute that can be used to override the default-generated tab sequence. Do not attempt to adjust tab index as a technique for getting past content blocks. Doing so will create a focus order that does not match the apparent visual order, as described in SC 2.4.3.

Examples

Example 1: User-enabled control that programmatically sets focus

The following is the XAML for the user interface.

   <StackPanel Name="LayoutRoot">
       <Button Name="bypassbtn1" Click="bypassbtn1_Click">Skip menus, go to main page content</Button>
       <!intervening content-->
       <StackPanel>
           <RichTextBox Name="rtb_MainContent" IsReadOnly="True">
           <Paragraph>Here is the main content ....</Paragraph>
           </RichTextBox>
       </StackPanel>
   </StackPanel>
   

The following is the event handler that forces focus.

       private void bypassbtn1_Click(object sender, RoutedEventArgs e)
       {
           rtb_MainContent.Focus();
       }

This example is shown in operation in the working example of Programmatic Focus.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Open the test HTML page for a Silverlight application.

  2. Check for a control that indicates that activating that control can skip to some particular region of the content.

  3. Activate that control. Verify that activating the control causes focus to go to that region, and that a repeated block or blocks of content are skipped.

Expected Results

#2 and #3 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL26: Using LabeledBy to Associate Labels and Targets in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL26. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the AutomationProperties.LabeledBy property to associate a non-interactive text label with an interactive field such as a Silverlight TextBox or RichTextBox. By using this technique, application authors can use the label text as the default source for AutomationProperties.Name on the target, and do not need to specify an explicit AutomationProperties.Name.

This technique relies on several Silverlight features: the Name property for identifying specific UI elements, the AutomationProperties API, and the ElementName variation of Silverlight data binding. AutomationProperties.Name can be set on and can target any Silverlight UIElement. The two most common uses of this labeling technique are for labeling a form field, and for associating an image caption with an image.

Examples

Example 1: Two TextBox form fields, each with a LabeledBy reference to a text label

The following is XAML for the UI (and can be inserted into a UserControl XAML root or elsewhere). No code-behind is necessary for this example; the element relationships are established by the {Binding} values in the XAML and interpreted appropriately by the Silverlight run time.

   <StackPanel x:Name="LayoutRoot" Background="White">
       <StackPanel Orientation="Horizontal">
           <TextBlock Name="lbl_FirstName">First name</TextBlock>
           <TextBox AutomationProperties.LabeledBy="{Binding ElementName=lbl_FirstName}" Name="tbFirstName" Width="100"/>
       </StackPanel>
       <StackPanel Orientation="Horizontal">
           <TextBlock Name="lbl_LastName">Last name</TextBlock>
           <TextBox AutomationProperties.LabeledBy="{Binding ElementName=lbl_LastName}" Name="tbLastName" Width="100"/>
       </StackPanel>
   </StackPanel>

This example is shown in operation in the working example of Labels.

Example 2: Labeling / captioning an image

       <Image HorizontalAlignment="Left" Width="480" Name="img_MyPix"
                Source="snoqualmie-NF.jpg"
                AutomationProperties.LabeledBy="{Binding ElementName=caption_MyPix}"/>
       <TextBlock Name="caption_MyPix">Mount Snoqualmie North Bowl Skiing</TextBlock>
       

Note: If the caption is not a usable text alternative, use the technique SL5: Defining a Focusable Image Class for Silverlight, or change the caption text.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. To see UI Automation, use Microsoft Windows as platform.

  2. Use a verification tool that is capable of showing the full automation tree. (For example, use UIAVerify or Silverlight Spy; see Resources links.)

  3. Verify that any element that has a LabeledBy value has an associated visible label.

  4. Verify that any element that has a LabeledBy value uses the Name value from that label.

Expected Results

#3 and #4 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL27: Using Language/Culture Properties as Exposed by Silverlight Applications and Assistive Technologies

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL27. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the combination of HTML Lang attribute, CultureInfo and Language to correctly specify the language of the entirety of Silverlight content, or of parts within the Silverlight content.

In general, Silverlight does not attempt to repurpose HTML Lang, because Silverlight is not HTML. Instead, internally within the Silverlight content area, Silverlight uses language definition concepts that relate to XML (Language is a remapping of xml:lang) or .NET Framework programming (CultureInfo). For these reasons, HTML Lang techniques as described in [H58] are not useful for Silverlight programming of Silverlight-specific "parts".

What becomes important in Silverlight application programming then is to make sure that the HTML language concept of Lang and the Silverlight language concept of CultureInfo or Lang are not at odds with one another, or reporting misinformation. In particular, application authors should avoid situations where an assistive technology has HTML Lang available for programmatic determination of either page or part, but the effective runtime language in the Silverlight part is different. The result here might be that a screen reader that changes functionality such as phonetic pronunciations would not correctly read the text content from the Silverlight content. Avoiding this situation is largely a matter of due diligence on the part of a Silverlight application author, OR on the part of the Web page author who authors surrounding HTML, in cases where a Web page is embedding Silverlight content or packages that the Web page's author did not actively develop and is only consuming/embedding.

The following is a general recommendation that summarizes the detailed discussion in subsequent subheadings:

  • If the Silverlight application does not have a strong emphasis on presenting textual information with a particular language association, HTML Lang should be left blank. This causes assistive technologies to defer to either user agent or platform language settings. Silverlight is able to determine these same language values at run time, and language behavior of assistive technologies and of Silverlight is kept synchronized through the use of the same external information set.

  • If the Silverlight application DOES have a strong emphasis on presenting textual information with A SINGLE particular language association, HTML Lang should be assigned to report that specific language either for whole page or at least for the Silverlight object tag. This enables assistive technologies to pick up the value, per H57: Using language attributes on the html element HTML. Aside from due diligence during development and deployment, Silverlight application code might choose to enforce that its runtime CultureInfo is really the same. This could be addressed with a specific HTML DOM helper function.

  • If the Silverlight application has MULTIPLE language associations, the best option is to separate the Silverlight application into object parts at the HTML level, to assure that HTML Lang and intended runtime language do not clash. This is particularly important if the application is actively resetting CurrentCulture away from the user settings of platform or user agent. For more information, see SL4: Declaring Discrete Silverlight Objects to Specify Language Parts in the HTML DOM.

HTML Lang

When Silverlight is embedded in an HTML document with the <object> element, the value of the HTML Lang attribute of the surrounding HTML becomes a factor. Browsers process the outer HTML, and the browser's processing has possible influence over values reported to any DOM script that acts, or to any accessibility framework that is reporting the browser content. The preferred way for a Silverlight application to address SC 3.1.1 is to correctly specify the HTML Lang value in the hosting HTML page. This technique should be used in conjunction with H57: Using language attributes on the html element HTML. By using the same language values with both techniques as a better practice, H57 will satisfy 3.1.1 while setting the language value of the Silverlight content to match will assist authors in meeting SC 3.1.2.

The Silverlight runtime itself does not attempt to inherit language settings that come from markup that is outside the Silverlight-specific content. In particular, the HTML Lang attribute applied to the html tag, Lang on host object tag, specific parameters of the Silverlight object tag, all have no affect on the value of any Silverlight Language attribute. Instead, the Silverlight Language defaults to the CultureInfo of the Silverlight runtime as instantiated by HTML object tag invocation. It is expected that if a Silverlight application contains extensive text where language of text is a factor for assistive technology purposes, developers will manually set the HTML Lang tag to match the Language value on the Silverlight root element in XAML. Development tools might or might not enforce or inform the relationship between HTML Lang and Silverlight Language; that consideration is outside the scope of Silverlight as a technology. If language is not a major factor in the application, application authors should consider leaving HTML Lang blank on the hosting HTML page.

You can programatically determine the value of HTML Lang of surrounding HTML from within the Silverlight API, by using the DOM-bridging method HtmlElement.GetAttribute. Otherwise, this can be determined by techniques other than Silverlight's (such as scripting to the HTML DOM of the hosting browser).

Silverlight Language property

Language is an attribute that is available on all Silverlight objects that directly represent a UI element. Language can be queried (or set) by Silverlight managed code run time, such that the Language value can be programatically determined within the Silverlight programming model.

The format of the value that is used to set Language is based on ISO-639-1, and is thus compatible with http://www.rfc-editor.org/rfc/bcp/bcp47.txt.

Language has a behavior that parallels the behavior of xml:lang in an XML document: if Language is set on a parent element, all child elements inherit that Language value. An actual xml:lang attribute in XAML is also valid for this purpose.

Language can be set at the root of a XAML document, so that the entire UI shares the same language setting. If Language is not explicitly set at the root by application markup, Language is inferred per running instance, based on processing the acting CultureInfo at run time.

However, another usage is for application authors to set Language on a specific child element, to override the root-level or client-environment-inferred Language value. This enables consciously embedding a content part that is deliberately in a different language than the remainder of the Silverlight content.

Exactly what happens when a Language is set on a part is not always specified, and is largely a matter of implementation detail of the individual Silverlight classes that might be a "part". However, as an informative generalization, the value of Language might affect considerations such as: how white space is processed (in particular CR or LF); character sets for fonts; string formatting when using APIs specifically on that part.

CultureInfo

CultureInfo is a concept that is relevant to .NET Framework programming. This concept applies to Silverlight because Silverlight uses a specific implementation of a CLR runtime that uses .NET Framework principles. CultureInfo potentially specifies both a language and a culture. This distinction becomes relevant for advanced string formatting concepts that are provided in the .NET Framework, such as decimal separators, dates, and currency. For example, an application author might simply specify "en" if the author did not care about string formatting, but might specify "en-GB" if the application was using string formatting for currency values with the intention of displaying Pounds Sterling as currency unit in string formatting.

Silverlight applications often run using an inferred CultureInfo based on the operating system where the user agent browser host exists (in other words, the culture of the client computer where the Silverlight application is run). This CultureInfo can be queried by applications at run time; see CultureInfo.CurrentCulture. Application authors can deliberately constrain the set of CultureInfo cases that a Silverlight application can be run under, in order to verify that necessary string resources for that culture are available in that application. This is done by setting <SupportedCultures> in the Silverlight project settings. If a user accesses the application on a client that is outside the SupportedCultures, the application author has the following choices:

  • Use a fallback resource set representing a neutral culture; this is enabled automatically by the Silverlight resources lookup behavior, so long as the project includes resources identified as being culture-neutral. This is the preferred approach.

  • Use client logic to detect the culture, and initiate a client-side redirect to request either a different XAP or a different hosting HTML page.

  • Trap requests at the server level by checking lang request in the header. This varies between server implementations, is not a Silverlight-specific technique, and is not discussed here.

For more information, see How to: Create a Build that Targets a Specific Culture.

CultureInfo generally applies to the Silverlight application as a whole. There are advanced techniques whereby worker threads can be run as separate cultures, but that is not discussed here and is not relevant because only the main UI thread has relevance to Web content accessibility. So, if an application author wants to declare specific language settings for a part (component, region or control) of the Silverlight application, a different Silverlight-specific property Language is used.

Examples

These examples show Silverlight behaviors that are based on interpreting the Language property value, as a way of illustrating the programmatic determination of language values specifically in the Silverlight application framework. To determine HTML Lang, application authors should use the HTML DOM as enabled by browser host scripting, rather than Silverlight APIs. HTML DOM techniques are not shown here because they are specific to browsers or scripting frameworks, not to Silverlight.

Example 1: Language set at root-level of Silverlight content, inherits

This example features a XAML UI and logic that reports information to demonstrate that the information is programmatically determinable. This example shows determination of the Language property.

<UserControl x:Class="LangProperties.MainPage" 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Language="en-gb">
 <StackPanel x:Name="LayoutRoot" Background="White">
       <Border BorderBrush="Red" BorderThickness="2">
           <TextBlock Language="zh-cn" Text="(()共" Name="t2" VerticalAlignment="Top" TextWrapping="Wrap" Height="100"/>
       </Border>
       <Border BorderBrush="Red" BorderThickness="2">
           <TextBlock Text="(()共" Name="t3" VerticalAlignment="Top" TextWrapping="Wrap" Height="100"/>
       </Border>
       <Button Click="button1_Click">IETF Language of this app</Button>
 </StackPanel>
</UserControl

private void button1_Click(object sender, RoutedEventArgs e)
{
   Button b = sender as Button;
   MessageBox.Show(b.Language.IetfLanguageTag);
   // this will be 'en-gb' because inherits from the root
}

This example is shown in operation in the working example of Language Properties.

Example 2: Determine CurrentCulture; runtime verification that CurrentCulture and the surrounding HTML's current Lang value do not report different language settings

The following is an event handler that can be hooked to an object lifetime event such as UserControl.Loaded on the Silverlight XAML root. This example demonstrates property access to several of the relevant language properties that are present in Silverlight and shows a specific way to compare CultureInfo and Lang by a "not equals" check after constructing a CultureInfo based on the Lang string. To apply this test, the hosting HTML page may need to be altered to declare a specific HTML Lang; default Silverlight aspx or html test pages do not declare HTML Lang.

       private void RunLanguageDetectLogic(object sender, RoutedEventArgs e)
       {
           CultureInfo thisAppCC = CultureInfo.CurrentCulture;
           CultureInfo thisAppCUIC = CultureInfo.CurrentUICulture;
           HtmlDocument thisPage = HtmlPage.Document;
           String thisAppHTMLLang = (string) thisPage.DocumentElement.GetProperty("lang");
           CultureInfo CCFromLang = new CultureInfo(thisAppHTMLLang);
           if (CCFromLang != thisAppCC && CCFromLang.ToString() !=  "")
           {
               TextBlock tb = new TextBlock();
               tb.Text += "Warning: the current culture for the run time (";
               tb.Text += thisAppCC.ToString();
               tb.Text += ") does not match the culture indicated in hosting HTML's Lang (";
               tb.Text += CCFromLang.ToString();
               tb.Text += ").";
               tb.Inlines.Add(new LineBreak());
               tb.Inlines.Add("Typical action here would be to redirect the request to an HTML page
                 where the Lang is correct for user's current culture as determined from the OS.");
               LayoutRoot.Children.Add(tb); 
               //LayoutRoot refers to the default MainPage.xaml element from a VS-template Silverlight Application
           }
       }

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Verify that language settings are respected by individual Silverlight control characteristics. (Exactly what behavior manifests the language difference varies per Silverlight class implementation. For some testing ideas, see Creating Globally Aware Applications).

  3. Verify that any interaction between HTML Lang in the HTML and the Language or CultureInfo from the Silverlight application do not result in a clash of language information, either in terms of basic application behavior or in how an assistive technology decides to process language information.

Expected Results

#2 and #3 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL28: Using Separate Text-Format Text Captions for MediaElement Content

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL28. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use text captioning that comes from a separate text file, synchronize the captions with the media in a Silverlight MediaElement, and display the captions in Silverlight.

There are two variations of the general theme of implementing Silverlight media player controls to work with external timed text: using built-in capabilities of the Microsoft Expression Encoder tool, and using parsing code that consumes caption as a raw file format and converts that format into the Silverlight API's TimelineMarkers representation. This technique primarily addresses how to use the Expression Encoder technique, along with media player templates that are also provided by Expression Encoder or related Silverlight SDKs such as the Smooth Streaming SDK.

At a pure architecture level, Silverlight uses the TimelineMarkers API to display caption text at synchronized times. The Expression Encoder and Expression Blend tools provide a front end to drive the TimelineMarkers API for the supported formats. The intention of the architecture is so that Silverlight as a run-time has a base architecture that could potentially use any existing or future timed text format, but the tools for Silverlight (rather than built-in features of the runtime) provide the optimized workflow for producing captioned media projects.

A procedure for using the Expression Encoder and Expression Blend tools to produce a Silverlight media player application that can consume timed text in TTML format is provided as Example 1 in this technique. (Note: prior to the approval of TTML by W3C, DFXP was a format that used much of the eventual TTML vocabulary. In tools that predate TTML, this format is often identified as DFXP.)

A purely code-based parsing technique, with the goal of avoiding Expression Encoder dependencies, is necessarily more complex. This is because there are multiple issues to solve:

  • Obtaining and validating the timed text file

  • Parsing the format into general information items like timings, text, format etc. that are either consumable directly in a Silverlight API, or useful as intermediates

  • Using the timecode information to create TimelineMarker representations for each timed text entity

  • Associating the TimelineMarkers with media loaded by the player

  • Finding a place to store the additional formatting that is conveyed, including the text and any formatting

  • Handling events from TimelineMarkers in the media player, in such a way that text and formatting behavior can be retrieved and presented in the Text part of the player UI

Text Captioning Formats

There are several existing text-based formats that are used for text captioning of prerecorded media. The following are supported as formats if using the Expression Encoder tool as shown in Example 1 (where the Expression Encoder generated Silverlight application uses the existing Silverlight MediaPlayerTemplate and the TimedTextLibrary component.) For more information on which timed text formats can be referenced in an Expression Encoder project, see About Captioning (Expression documentation on MSDN).

  • SAMI (Synchronized Accessible Media Interchange). For more information on this format, see Understanding SAMI 1.0 on MSDN.

  • SMIL (Synchronized Multimedia Integration Language). For more information on this format, see Synchronized Multimedia Integration Language (SMIL 3.0) on W3C site.

  • TT (Timed Text) in particular TTML (Timed Text Markup Language). For more information, see Timed Text Markup Language (TTML) 1.0 on W3C site.

  • TTML (previously known as DFXP). This is the Timed Text format used by Adobe Flash for its FLVPlaybackCaptioning component, and is produced by a variety of tools and full-service captioning vendors. For more information, see Captions on the Adobe site.

The following are not supported directly in Expression Encoder templates. To use these formats, application authors would have to write parsing logic, as shown in Example 2:

  • MPEG Part 17 / 3GPP Timed Text. For more information, see ISO/IEC 14496-17:2006 on ISO site.

  • Other formats that have not realized wide adoption, for example Universal Subtitle Format.

  • In addition to these formats, other formats for device-specific recorded media (such as DVD encoded tracks) could be cross-purposed for use by streaming/online media.

Rather than build the parsing logic for all these formats into the Silverlight runtime, or choosing just one of these formats to support, the Silverlight design for text captioning at the core level instead makes the TimelineMarkers property of a MediaElement writeable, independently of the value of Source. The format of each TimelineMarker in the collection is very simple: a time value expressed in the format, and the text value of the text for that synchronized caption. The time format for TimelineMarkers is documented as TimelineMarker reference on MSDN. Converting timed text formats to TimelineMarkers form as consumed by the Silverlight core can be done by following any of the following application design patterns:

  • Authoring the project using Expression Encoder, and using the Expression MediaPlayerTemplate as the media player UI. In this case, Expression produces a Silverlight application that includes assemblies that are generated from code templates. The default build of the project provides a working library that handles all tasks related to timed-text format conversion, from the formats as documented at About Captioning (Expression documentation on MSDN).

  • The templates of an Expression Encoder project can also be edited, either editing the XAML for the UI by altering the template, or by altering the C# code files that define various aspects of the media player logic, including the timed text format parsers. Then the project can be rebuilt using the desired customizations. Using this technique, it is possible to adapt the code to support timed text formats that are not directly supported in the Expression Encoder project UI.

  • Using a 3rd party media player implementation that also includes a codebase for processing timed text formats, producing TimelineMarkers, and displaying the captions in the player-specific UI.

  • Including a library that handles just the format parsing, and using APIs of this library as part of the Silverlight application code-behind.

  • Writing all logic that is necessary for timed text parsing AND application UI display, and including it all in the main Silverlight application library.

Examples

Example 1: Using Expression Encoder and Expression Blend to produce a Silverlight media player project from tool output and templates

By far the simplest technique for incorporating existing timed-text information is to use Microsoft Expression Encoder and the media player templates that an Expression Encoder project produces by default. You can use timed text in any of the following formats: DFXP, SAMI, SRT, SUB, and LRC. Associating a caption file with a media source is done as an "import" operation in the Expression Encoder tool. However, the "import" does not necessarily mean that the timed text file is integrated into the media stream; Silverlight authors have the option to preserve the file separation. This is useful if the application is obtaining timed text from a third party source in real-time, or if Silverlight authors have a production pipeline that makes it difficult to have the captioning ready in time to be encoded in the stream along with the audio-visual source files. For third-party timed text files that are served directly from the third party's HTTP servers, it can be useful to supply a dummy URL in the initial project encoding. The output of the Expression Encoder project parameterizes many of the project settings at the HTML level. This makes it possible to change the URL at any time prior to deployment without having to rebuild the project. The following code is the HTML output of a sample Expression Encoder project. Note the CaptionSources node in the initparams; that is the information item that informs the Expression Encoder templates where to find the timed text file.

     <object data="data:application/x-silverlight," type="application/x-silverlight" width="100%" height="100%">
       <param name="source" value="MediaPlayerTemplate.xap"/>
       <param name="onerror" value="onSilverlightError" />
       <param name="autoUpgrade" value="true" />
       <param name="minRuntimeVersion" value="4.0.50401.0" />
       <param name="enableHtmlAccess" value="true" />
       <param name="enableGPUAcceleration" value="true" />
       <param name="initparams" value='playerSettings = 
         <Playlist>
           <AutoLoad>true</AutoLoad>
           <AutoPlay>true</AutoPlay>
           <DisplayTimeCode>false</DisplayTimeCode>
           <EnableOffline>false</EnableOffline>
           <EnablePopOut>false</EnablePopOut>
           <EnableCaptions>true</EnableCaptions>
           <EnableCachedComposition>true</EnableCachedComposition>
           <StretchNonSquarePixels>NoStretch</StretchNonSquarePixels>
           <StartMuted>false</StartMuted>
           <StartWithPlaylistShowing>false</StartWithPlaylistShowing>
           <Items>
             <PlaylistItem>
             <AudioCodec></AudioCodec>
             <Description></Description>
             <FileSize>2797232</FileSize>
             <IsAdaptiveStreaming>false</IsAdaptiveStreaming>
             <MediaSource>thebutterflyandthebear.wmv</MediaSource>
             <ThumbSource></ThumbSource>
             <Title>thebutterflyandthebear</Title>
             <DRM>false</DRM>
             <VideoCodec>VC1</VideoCodec>
             <FrameRate>30.00012000048</FrameRate>
             <Width>508</Width>
             <Height>384</Height>
             <AspectRatioWidth>4</AspectRatioWidth>
             <AspectRatioHeight>3</AspectRatioHeight>
             <CaptionSources>
               <CaptionSource Language="English" LanguageId="eng" Type="Captions" Location="thebutterflyandthebear.eng.capt.dfxp"/>
             </CaptionSources>
           </PlaylistItem>
         </Items>
      </Playlist>'/>       
   </object>
   

The templates include a library that handles any parsing requirements for the chosen timed text format, both at the level of getting the basic text and timing into the TimelineMarkers used by the run-time MediaElement, and for preserving a subset of format information that can reasonably be crossmapped from the formatting paradigm of the source (typically HTML/CSS) into the Silverlight text object model of the text element that displays the captions in the running Silverlight application.

The following is a brief description of the procedure for creating a project that incorporates a separate timed text file.

  1. From the initial Expression Encoder screen, select New Project from the File menu.

  2. In the Load a new project dialog, select Silverlight Project.

  3. From the File menu, select Import. Choose the primary media source file the project will use.

  4. In the Text tab, find the listing for the media source file. Click the + icon to the right of the file name. This opens a file dialog.

  5. Choose a timed text file to add to the project.

  6. Build the project. By default the project produces a complete output folder. The folder includes the media player template XAP, the timed text file as a separate file, and additional libraries and XAPs that support the basic template and/or the timed text capabilities.

  7. Optionally, use the features in the Templates tab of Expression Encoder to generate a template copy. You can edit the template copy in other tools such as Expression Blend or Visual Studio, to change the layout or behavior from the default media player template. Template editing can address requirements such as applying a particular branding or "look" to the player user interface.

The following is a screenshot of the Expression Encoder (version 4) interface. The + icon mentioned in Step 4 is highlighted in this screenshot with a red diamond. The Templates tab mentioned in Step 7 is on the right side, top-middle. Note that all tabs of an Expression user interface are dockable; the orientations shown here are the default, but could be in different locations on any given computer or configuration.

Expression Encoder screenshot

Example 2: Code parses timed text; MediaElement handles MarkerReached, displays marker text in application-defined TextBox

This example defines a very simple media player class that includes a display surface, basic controls, and a text display for captions as part of its default template. The usage code for this control in XAML is simple, but only because the majority of the implementation is present in the definition of the media player class.

The following is example usage XAML:

 <local:SimpleMediaPlayerWithTT Width="480" Height="360" CaptionUri="testttml.xml" MediaSourceUri="/xbox.wmv" />
    					

Note the attributes CaptionUri and SimpleMediaPlayerWithTT. Each of these is a custom property of the media control class TTReader. CaptionUri in particular references a URL, in this case a local URL from the same server that serves the Silverlight XAP. The timed text file could come from a different server also, but comes from a local server in this example to conform to the behavior of the test file.

The following is the generic.xaml default template for the media player control. The template is mainly relevant for showing the named elements that are shown in the initialization code.

               <ControlTemplate TargetType="local:SimpleMediaPlayerWithTT">
                   <Border Background="{TemplateBinding Background}"
                           BorderBrush="{TemplateBinding BorderBrush}"
                           BorderThickness="{TemplateBinding BorderThickness}">
                       <Grid x:Name="vroot">
                           <Grid.RowDefinitions>
                               <RowDefinition Height="*"/>
                               <RowDefinition Height="50"/>
                               <RowDefinition Height="80"/>
                           </Grid.RowDefinitions>
                           <MediaElement x:Name="player" AutoPlay="False"/>
                           <StackPanel Orientation="Horizontal" Height="50" Grid.Row="1">
                               <Button x:Name="player_play">Play</Button>
                               <Button x:Name="player_pause">Pause</Button>
                               <Button x:Name="player_stop">Stop</Button>
                           </StackPanel>
                           <ScrollViewer x:Name="scroller" Height="50" Grid.Row="2">
                           <TextBox IsReadOnly="True" x:Name="captions"/>
                           </ScrollViewer>
                       </Grid>
                   </Border>
               </ControlTemplate>
               

The following is the initialization code that is for general infrastructure. OnApplyTemplate represents the code wiring to the template-generated UI.

   public class SimpleMediaPlayerWithTT : Control
   {
       MediaElement player;
       TextBox captions;
       public SimpleMediaPlayerWithTT()
       {
           this.DefaultStyleKey = typeof(SimpleMediaPlayerWithTT);
       }
       public override void OnApplyTemplate()
       {
           base.OnApplyTemplate();
           player = this.GetTemplateChild("player") as MediaElement;
           captions = this.GetTemplateChild("captions") as TextBox;
           scroller = this.GetTemplateChild("scroller") as ScrollViewer;
           //event hookups and prop inits
           player.MediaOpened += new RoutedEventHandler(OnMediaOpened);
           player.MediaFailed += new EventHandler<ExceptionRoutedEventArgs>(OnMediaFailed);
           player.Source = this.MediaSourceUri;
           player.MarkerReached+=new TimelineMarkerRoutedEventHandler(player_MarkerReached);
           Button player_play = this.GetTemplateChild("player_play") as Button;
           player_play.Click += new RoutedEventHandler(player_play_click);
           Button player_pause = this.GetTemplateChild("player_pause") as Button;
           player_pause.Click += new RoutedEventHandler(player_pause_click);
           Button player_stop = this.GetTemplateChild("player_stop") as Button;
           player_stop.Click += new RoutedEventHandler(player_stop_click);
       }
       // mediaelement in template events
       void OnMediaOpened(object sender, RoutedEventArgs e)
       {
           LoadCaptions(captionUri);
       }
       void OnMediaFailed(object sender, ExceptionRoutedEventArgs e)
       {
       }
       void player_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
       {
           captions.SelectedText = e.Marker.Text + "\n";
           scroller.ScrollToVerticalOffset(scroller.ScrollableHeight);
       }
       void player_play_click(object sender, RoutedEventArgs e)
       {
           player.Play();
       }
       void player_pause_click(object sender, RoutedEventArgs e)
       {
           player.Pause();
       }
       void player_stop_click(object sender, RoutedEventArgs e)
       {
           player.Stop();
       }
       // properties
       private Uri captionUri;
       public Uri CaptionUri
       {
           get { return captionUri; }
           set { captionUri = value; }
       }
       private Uri msUri;
       public Uri MediaSourceUri
       {
           get { return msUri; }
           set { msUri = value; }
       }
       

The following is the logic that is particular to obtaining the separate caption file. Some of this logic is referenced in the preceding template-specific event handlers. This example uses the asynchronous WebClient technique to request the file result of the CaptionUri. Make sure to use AutoPlay=false or some other means to allow time for the caption file to download before attempting to play the media file.

       private void LoadCaptions(Uri captionURL)
       {
           WebClient wc = new WebClient();   // Web Client to download data files
           if (captionURL != null)
           {
               wc.DownloadStringCompleted +=
                   new DownloadStringCompletedEventHandler(OnDownloadStringCompleted);
               wc.DownloadStringAsync(captionURL);
           }
       }
       private void OnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
       {
           if (!e.Cancelled && e.Error == null && e.Result != "")
           {
               string xml = e.Result.Trim();
               ParseCaptionData(new StringReader(xml));
           }
       }
       

The actual parsing can be done using a combination of the "XML to Linq" facilities of an optional Silverlight library, and standard .NET Framework string format APIs from the Silverlight core. An implementation is NOT provided here, due to length considerations. TTML supports a number of profiles and capabilities. The basic pattern to follow in the implementation is to obtain the necessary text and timing information, and to pass it to a function that might resemble the following code template. This code template takes the raw information, generates a new TimelineMarker, and adds it to the collection assigned to the active MediaElement as identified by "player" in the application.

       public void AddMediaMarker(string time, string type, string data)
       {
           TimelineMarker marker = new TimelineMarker();
           marker.Time = new TimeSpan(0,0,(Convert.ToInt32(time.Trim())/1000));
           // this logic could vary depending on how time is formatted in the input string; this one assumes raw milliseconds
           marker.Type = type;
           marker.Text = data.Trim();
           player.Markers.Add(marker);
       }

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. That application plays media that is expected to have text captioning.

  2. Check that the text area in the textbox shows captions for the media, and that the captions synchronize with media in an expected way.

Expected Results

#2 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL29: Using Silverlight "List" Controls to Define Blocks that can be Bypassed

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL29. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use some of the basic user interface objects in Silveright to produce blocks of content that are identified as a "List" to accessibility frameworks and to Silverlight's own tab sequence navigation behavior.

Using the "List" technique results in a tab sequence behavior whereby that element is treated as a single tab stop, even if that element has consituent elements (the list items) that would otherwise be considered additional tab stops in the main tab sequence. In the default key handling, when the user presses the TAB key while focus is on a List, the focus goes to the next element after the List. To focus the items of the list, the user would press the Arrow keys rather than TAB. In the Silverlight programming model for controls, this tab sequence behavior is expressed by the TabNavigation property holding the value of Once. The Silverlight ListBox is a control that reports itself as "List" role, and that has a default TabNavigation.Once value. Thus ListBox as per this technique is a lightweight technique for producing blocks that can be bypassed. It is specifically a lightweight technique because it can be accomplished by writing simple application-level XAML and using only the Silverlight core libraries.

Silverlight also supports more full-featured techniques for producing bypass blocks that are based on common user interface features such as menus or toolbars. However, using toolbars in Silverlight is inherently not as lightweight because the Silverlight core libraries themselves do not include a ready-made toolbar. Silverlight provides a ContextMenu as part of the Silverlight Toolkit extensions, but the behavior of this particular menu does not easily address the bypass block scenario. Silverlight includes all the infrastructure and necessary base classes for defining a toolbar or a menu that could address the bypass block scenario. Many third-party control implementations of menus and toolbars exist, either as part of control packages that are sold by control vendors, or through community mechanisms such as CodePlex or third-party sites that provide free source code. For some examples, see the following:

If application authors use a built-in control such as ListBox where the accessibility framework reported role is not traditionally associated with a navigation role, it is a best practice to set AutomationProperties.Name such that the name informs the user of the purpose of the list control. Otherwise, the role alone leaves this ambiguous. For example, an author might name the list control "Navigation control".

Often the List control itself is focusable. So long as the List control has a visual focus indicator, that behavior might be acceptable. However, it might provide a better user experience to deliberately have the List itself non-focusable, and instead have focus fall to the first List item when focus reaches that region. Otherwise, the List might be perceived as an "extra" tab stop to some users. To enable that behavior, set IsTabStop to false on the List control. The List itself still provides the intended tab navigation behavior, and is still reported and identified to accessibility frameworks and assistive technologies, even when the List container is not focusable. This is shown in Example 1, by setting IsTabStop as part of a Style.

When an accessibility framework presents a List, assistive technologies are generally expected to continue to support use of the same key behavior as the default behavior, and to report to users that the item is a List when it is focused. If assistive technologies use the accessibility framework APIs for navigation, the items in the list are considered child elements. Navigating either by spatial direction (e.g. NAVDIR_RIGHT in MSAA) or sequential direction (e.g. NAVDIR_NEXT in MSAA) skips the list items and goes to the spatial/next peer.

Examples

Example 1: Customize the behavior and appearance of a ListBox to construct a navigation control that can be bypassed

In this example, several properties that influence the items presentation behavior of the Silverlight core control ListBox are adjusted to make it suitable for a navigation control. The behavior of this control is that when the tab sequence reaches the control, "next" or spatial navigation continues on to other controls, rather than through the child controls of the list's items/options. This is enabled and properly reported because ListBox reports its accessibility framework role as "List", uses TabNavigation = Once as default (because it is the default, TabNavigation does not have to be set explicitly in the markup). ListBox has default key handling for the arrow keys (to enable traversing the choices in the menu by keyboard-only). The control could also be visually a menu or perhaps other user interface control metaphors, depending on how it is visually templated and composited. Regardless of appearance, the accessibility framework and any assistive technologies based on that framework will treat the control as a "List". This example is templated as a horizontally oriented toolbar-type control. The items in this example are Button controls, but could be templated to not appear quite as button-like, or could instead use another focusable control for the items such as a read-only TextBox.

<UserControl x:Class="TabNavigation.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
   <StackPanel x:Name="LayoutRoot" Background="White">
       <ListBox AutomationProperties.Name="Navigation Control">
           <ListBox.ItemsPanel>
               <ItemsPanelTemplate>
                   <StackPanel Orientation="Horizontal"/>
               </ItemsPanelTemplate>
           </ListBox.ItemsPanel>
           <ListBox.ItemContainerStyle>
               <Style TargetType="Control">
                   <Setter Property="IsTabStop" Value="False"/>
               </Style>
           </ListBox.ItemContainerStyle>
           <Button>Home</Button>
           <Button>Search</Button>
           <Button>Tools</Button>
           <Button>Help</Button>
       </ListBox>
   </StackPanel>
   <Button>Button here to show a focusable peer control beyond the list</Button>
</UserControl>

The following is an illustration of what such a control might look like:

Screen shot of a focusable control beyond a list of buttons

This example is shown in operation in the working example of Tab Navigation.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Press TAB key to traverse typical tab sequence within the Silverlight application. Verify that common areas in the user interface composition ("blocks") that are reporting the List role per this technique can be bypassed without having to tab through each constituent part (the "items/children" of the List).

  3. Verify that the list children are still accessible by keyboard, by using ARROW keys rather than TAB.

  4. Engage an accessibility framework test tool such as UIAVerify. Examine roles in the automation tree, and verify that the List used for bypass behavior reports a combination of name+role that is consistent with the behavior.

  5. Use a screen reader to verify that name and role are reported properly.

Expected Results

#2 and #3 are true, and either #4 OR #5 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL30: Using Silverlight Control Compositing and AutomationProperties.Name

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL30. Also see Silverlight Technology Notes.

Description

The objective of this technique is to properly apply Silverlight control composition techniques that can present text and non-text in UI as part of the same control. This technique explains the consequences that using control composition has on how that control is reported to the accessibility frameworks that Silverlight supports.

Silverlight control composition concepts are relevant either to Silverlight developers who define and package a Silverlight control for use by other Silverlight authors, or for Silverlight application authors that use Silverlight controls in their UI but use the content properties of such controls to include several other elements in a composite layout.

In Silverlight programming and UI definition, Silverlight authors can use control composition to define a parent control that initiates an action. The control can have component parts, such as text and non-text composition pieces that display within the control and have equivalent meaning. Silverlight authors can rely on the text component of the control to provide any text alternative for purposes other than the accessibility framework. However, Silverlight authors should declare alternative text on the control that is specifically consumed by accessibility frameworks, by setting AutomationProperties.Name as an attribute in XAML. In most cases, this text can be the same as the visible text in the control composition, per the definition of 'label' in SC 4.1.2.

Note that this technique does not result in a duplication of text, as explained in H2. This is because the element parts of control composition are either inherently not focusable separately, or can be specified by instance-specific properties to behave as if they cannot be focused. The parts in Silverlight composition are not promoted to the accessibility frameworks as parts of an application-specific UI Automation tree, so that control composition as an implementation detail does not interfere with the usage of controls by Silverlight application authors. The primary source of accessibility-related information is the specific AutomationProperties.Name property as set on the parent control in the composition, which is set by the application author rather than the control author.

The control author does specify the information that is reported to accessibility frameworks as the "ClassName", which is often used by assistive technologies for identification purposes and is appended to any "Name" value. For example, if an application author includes a "Widget" control, and gives it an AutomationProperties.Name value of "Show Map", an assistive technology might identify the element as "Show Map widget". The "Show Map" part comes from the application author code, and the "widget" part comes from the Widget control implementation code.

Examples

Example 1: Button is composed with a StackPanel that contains nontext and text content

In this example the TextBlock that goes with the graphic image conveys the text information for non-accessibility purposes. The Button has internal composition that combines text from a non-focusable TextBlock part and an image part. Therefore the "Pause" Text is not promoted to serve as "Name" through built-in Button automation peer logic. The Silverlight application author is responsible for explicitly setting AutomationProperties.Name on the Button so that the text equivalent is available to the accessibility framework. This example shows the XAML UI. The logic, which might be attached to Button with a Click handler, is not shown.

 <Button
   Height="20" Width="50" AutomationProperties.Name="Pause" 
 >
   <StackPanel Orientation="Horizontal" >
     <Image Height="12" Width="12" Source="/icon_pause.png"/>
     <TextBlock Text="Pause"/>
   </StackPanel>
 </Button>

This example is shown in operation in the working example of Button Nontext Text Composition.

Example 2: Button composed, using binding and resource references for strings

This example is similar to Example 1 and produces the same result at run time. This example shows the preferred technique of using the Silverlight data binding and resource features to ensure that the strings for text content and accessibility are the same strings. Also, this gets the strings out of the XAML source and makes them simpler to localize or edit. For more information on using resource strings through binding, see Localizing XAML topic on MSDN.

 <Application.Resources>
  <resx:Resources x:Key="UIResourceStrings" />
 </Application.Resources>
  ...
 <Button
   Height="20" Width="50"
   AutomationProperties.Name="{Binding PauseUIString, Source=UIResourceStrings}" />
 >
   <StackPanel Orientation="Horizontal" >
     <Image Height="12" Width="12" Source="/icon_pause.png"/>
     <TextBlock
       Text="{Binding PauseUIString, Source=UIResourceStrings}"/>
   </StackPanel>
 </Button>

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Automation tree verifier

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Use a verification tool that is capable of showing the full automation tree, and an object’s name text alternative as part of the tree. (For example, use UIAVerify or Silverlight Spy; see Resources links.)

  3. Check that the AutomationProperties.Name appears as the Name value for identification in the automation tree, whenever a composite control that has both text and non-text elements is encountered.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.

Tests

Screen reader

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Engage the screen reader. With focus inside the Silverlight content area, press TAB to focus to a composite control where both text and non-text elements are present.

  3. Check that the Name as applied to the control instance, along with the class name of the control, is read by the screen reader.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL31: Using Silverlight Font Properties to Control Text Presentation

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL31. Also see Silverlight Technology Notes.

Description

The objective of this technique is to change the presentation / visual appearance of text, by setting several of the font-specific properties in the Silverlight API. Changing such properties does not change the semantic meaning of the text, nor does it alter the representation of the text that is available to assistive technologies through the Silverlight support of the UIA accessibility framework. By using font properties, it is possible to introduce a wide variety of presentation changes to fonts that do not introduce semantic elements that interfere with an assistive technology's view of text in the Silverlight application. In particular, adjusting font properties will make it possible to avoid any need for use of images of text, yet still provide a wide range of choices for text presentation.

Silverlight font properties exist on all controls, as well as on other text elements that are not true controls. For controls, the font properties apply in any case where the control enables a presentation mode that has enclosed text areas in its layout. By setting Silverlight font properties, it is possible to adjust presentation of font features without changing the structural connotation of that control, or the value of any control-specific property that contains plain-text. For example, the FontSize property can be set on a Paragraph (not a control) or on a Button (a control, and in this case the font size changes apply to any text displayed in the button content area). Font properties are also inheriting properties, meaning that if applying a font property value to a container in a relationship, those font property values can apply to child elements in the relationship. For example, if a FontSize is applied to a RichTextBox, that FontSize value is used by default by all the Paragraph items displayed in the RichTextBox.

Similar to CSS, Silverlight font properties can be grouped as a Style. That Style can be applied to all instances of a text element type (for example to all cases of Paragraph) or specifically referenced as a resource that is only used by certain instances of a text element type. Either way, the Style feature enables the separation of presentation from semantics for text elements, and enables workflows where content authors supply the semantic text and design-oriented authors adjust the related Silverlight styles. For more information on the Silverlight concept of styles, see Control Customization on MSDN.

The following Silverlight font properties are useful to style text and avoid the need for text in images. Links in this list refer to the Control class version of these properties.

  • The FontFamily property is used to display the code aspect in a monospace font family (specifically, FontFamily="Courier New").

  • The FontSize property is used to display the text in a larger size.

  • The FontStyle property is used to display text in italics.

  • The FontWeight property is used to set how thick or thin characters in text should be displayed.

  • The FontStretch property is used to control the spacing of letters in text.

  • The Foreground property is used to display the color of text or text containers.

  • The Background property can be used to display text on a non-text background.

So long as images of text are avoided, the text within a Silverlight text element can be reported to the UI Automation accessibility framework that Silverlight supports. That text is reported using the same basic text content as is used for semantic text display in the UI. In other words, exposing that text to assistive technologies that use UIA as a framework does not require the Silverlight application author to resort to automation-specific override properties such as AutomationProperties.HelpText; the automation peers for text elements report all necessary text content to automation as a built-in behavior of the text element controls. For more information on UI Automation and text containers, see SL32: Using Silverlight Text Elements for Appropriate Accessibility Role.

CSS versus Silverlight font properties

Related CSS techniques mention that users can override any page-declared CSS styling techniques, by invoking browser-specific features. For example, using Internet Explorer, a user can use Tools / Internet Options, Appearance / Accessibility to override certain classifications of CSS-controlled font properties when displaying HTML documents, or to use a user-specific style sheet for HTML documents. No browser-level equivalent feature exists for user alteration of Silverlight text properties in the Silverlight content area. Instead, application authors could supply controls that enable similar font-property changing behavior, and include those controls in the application-specific user interface. For more information on this technique, see SL13: Providing A Style Switcher To Switch To High Contrast.

Glyphs

Silverlight API includes a related text presentation API Glyphs. Glyphs is intended for specific decorative or niche language-support scenarios. The Glyphs API does not offer as much UIA exposure or the ability to programmatically change typical font properties; the main scenarios for Glyphs are to package migrated text content from document formats, or for purely decorative text in a font that is not commonly found on a user system and only the glyphs actually used in the Unicode string are subsetted into the Glyphs font payload. If addressing the WCAG criteria, authors should avoid using Glyphs API and instead use other text containers such as TextBox, along with a font that is supplied in the application package or known to exist on the end user system.

Examples

Example 1: Run time applied font properties, style, and template

This example illustrates applying runtime changes to a font property.

This example has UI in XAML, and logic in C#. The following is the XAML.

<UserControl x:Class="DocumentStructure.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
   <UserControl.Resources>
       <Style x:Key="NewStyle" TargetType="Control">
           <Setter Property="FontFamily" Value="Arial"/>
           <Setter Property="FontSize" Value="30"/>
           <Setter Property="Height" Value="40"/>
       </Style>
   </UserControl.Resources>
   <StackPanel x:Name="LayoutRoot" Background="White">
   <RichTextBox IsReadOnly="True" Name="rtb" FontFamily="Algerian" FontSize="20">
           <Paragraph>Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, 
           and nothing particular to interest me on shore, I thought I would sail about a little 
and see the watery part of the world. It is a way I have of driving off the spleen and 
regulating the circulation. Whenever I find myself growing grim about the mouth; whenever 
it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before 
coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my 
<Hyperlink NavigateUri="http://en.wiktionary.org/wiki/hypo">hypos</Hyperlink>
get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into 
the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can. 
This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself 
upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, 
almost all men in their degree, some time or other, cherish very nearly the same 
feelings towards the ocean with me.
           </Paragraph>
           <Paragraph>There now is your
               <Hyperlink 
               NavigateUri="https://en.wikipedia.org/wiki/New_York_Harbor">insular city of the Manhattoes</Hyperlink>
, belted round by wharves as Indian isles by coral reefs--commerce surrounds it 
with her surf. Right and left, the streets take you waterward. Its extreme downtown is the 
battery, where that noble mole is washed by waves, and cooled by breezes, which a few hours 
previous were out of sight of land. Look at the crowds of water-gazers there.
           </Paragraph>
           <Paragraph>Circumambulate the city of a dreamy Sabbath afternoon. 
Go from Corlears Hook to Coenties Slip, and from thence, by Whitehall, northward. What do you see?
--Posted like silent sentinels all around the town, stand thousands upon thousands of mortal men 
fixed in ocean reveries. Some leaning against the spiles; some seated upon the pier-heads; 
some looking over the bulwarks of ships from China; some high aloft in the rigging, as if striving 
to get a still better seaward peep. But these are all landsmen; of week days pent up in lath 
and plaster--tied to counters, nailed to benches, clinched to desks. How 
then is this? Are the green fields gone? What do they here?
           </Paragraph>
       </RichTextBox>
       <Button Name="swapper" Click="swapper_Click" Width="220">Swap styles</Button>
   </StackPanel>
</UserControl>

The following is C# code:

       private void swapper_Click(object sender, RoutedEventArgs e)
       {
           rtb.Style = this.Resources["NewStyle"] as Style;
       }

This example is shown in operation in the working example of Document Structure.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Test that application of font properties as enabled in application UI changes presentation, but does not change semantic meaning of text.

  3. Close the browser. Repeat the test with an accessibility framework test tool running. There should be no difference in the structure or relationships in the accessibility view beyond the presentation changes.

Expected Results

#2 and #3 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL32: Using Silverlight Text Elements for Appropriate Accessibility Role

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL32. Also see Silverlight Technology Notes.

Description

The objective of this technique is to choose a Silverlight text container that provides appropriate behavior and accessibility roles for different types of text content. How those roles interact with existing assistive technologies that are interpreting Silverlight under the larger concept of being an "HTML control part" is also a factor in which Silverlight text container should be used in an application's composition.

Text containers can identified by role to accessibility frameworks, and each type of Silverlight text container uses a different role. Application authors should choose text containers that combine the desired behavior in the user interface with an accessibility role that can be consumed by existing assistive technology implementations.

The Silverlight core libraries define the following classes that are specifically intended as text containers:

UI Automation programmatic access

For programming information that is relevant for how Silverlight application authors produce the application, each text container has its own object model/API. That API is documented on MSDN, specifically for each class TextBox; RichTextBox; TextBlock.) However, rather than using the Silverlight-specific object models, most assistive technologies that are capable of reporting on Silverlight will choose to use UI Automation (or MSAA) to obtain information about the Silverlight elements in general. Text containers within the Silverlight content are identified through UIA accessibility roles. This is because the assistive technologies can use UI Automation to query for ANY relevant text items from the content (and chrome) of the user agent / browser host, not just those that come from Silverlight. That can include the HTML content, items created from scripting, CSS or other plugin-internal object models and so on. In other words, text from Silverlight is integrated into the overall UI Automation view of the user agent host as the top-level application in a platform view. Different types of "text" in a general sense might appear as different UI Automation patterns, as is described below.

TextBox

A TextBox within the Silverlight content area is reported to UI Automation as an Edit role (through MSAA, as Editable Text).

Edit controls are expected to implement the Value pattern for UIA, so that the value of the edit area can be queried or set by a client. Assistive technologies can use this value as a text-string value for screen readers or other purposes.

In typical user interface design, a form with an input field also includes a label or other explanatory text that is proximally close to the input field. In order to maintain proper reading order, the label should typically appear immediately before the input field. This general model should also be used for Silverlight user interface design. For more information on labeling for TextBox controls, see SL26: Using LabeledBy to Associate Labels and Targets in Silverlight.

RichTextBox

A RichTextBox within the Silverlight content area is reported to UI Automation and MSAA as a Document role.

A RichTextBox can either be set to be a read-only control, or left as a read-write control. In the latter case, users can insert a text cursor and make changes to the text. It is more common in Silverlight programming to set the RichTextBox to be read-only; in this scenario the reason for using RichTextBox is because TextBlock did not offer the range of text formatting options that are possible from a RichTextBox.

In UIA, a document is generally expected to support the Text pattern for UI Automation. However, to read the text from a RichTextBox, the assistive technology does not necessarily have to implement code that handles the entirety of the information that the Text pattern reports.

More about the Text pattern

The Text pattern provides APIs to iterate over the internal structure of a document and return text ranges. Each such text range can be queried for specific properties, and can return its plain text string value to UI Automation. Ranges can also be programmatically adjusted by the TextPattern/TextRange APIs. The following is a snippet of a Silverlight-specific UI Automation tree utility to give a general idea of the APIs involved. Note that these are not specifically Silverlight APIs; they are .NET Framework APIs. .NET Framework or Windows Automation APIs are generally what is used for programming a UI Automation client, which runs on a platform runtime rather than the Silverlight runtime. Using the Text pattern is generally what is necessary in order for an assistive technology to obtain a comprehensive view of the "value" for a document role object.

private void FindTheTextPatterns_Click(object sender, RoutedEventArgs e)
{
   if (allSilverlight != null && allSilverlight.Count>0)
   {
       //for simplicity just processing item 0, not assuming more than one SL control
       //on the page because this app controls the page being loaded
       AutomationElementCollection documentsList = allSilverlight[0].FindAll(TreeScope.Descendants,
           new PropertyCondition(AutomationElement.ControlTypeProperty,ControlType.Document)
   );
   for (int j=0; j< documentsList.Count;j++) {
       TextPattern targetTextPattern = 
         documentsList[j].GetCurrentPattern(TextPattern.Pattern) as TextPattern;
       if (targetTextPattern!=null) {
           TextPatternRange tr = targetTextPattern.DocumentRange;
           MessageBox.Show(tr.GetText(Int16.MaxValue));
       }
   }
}
private void GetAllSilverlight()
{
   allSilverlight = this._clientAppRootInstance.FindAll(TreeScope.Descendants,
      new PropertyCondition(AutomationElement.ClassNameProperty, "MicrosoftSilverlight"));
}

MSAA has only limited possibilities for interacting with a Document role, and MSAA code for attempting to do so is not shown.

TextBlock

TextBlock is reported as a Text role in UI Automation. TextBlock has several important characteristics:

  • A TextBlock is always read-only; only the application author can declare the text, users cannot change it.

  • A TextBlock is not considered to be a true control in the Silverlight object model (it is not a class derived from Control). The practical implications of this to accessibility scenarios is that a TextBlock is not in the default tab sequence, cannot be manually added to any tab sequence, and cannot be keyboard-focused either programatically or by the user.

  • TextBlock has a deliberately limited range of block / span formatting options. If the application author desires a wider range of formatting options, for example supporting a "Paragraph" metaphor for blocks of text, a read-only RichTextBox should be used instead.

If the user relies solely on navigating a Silverlight application using the TAB sequence, such navigation will skip over any TextBlock in the interface. This could have implications for how users who use screen readers can interact with the Silverlight content. Screen readers typically read text only from the currently focused element in cases where the user is moving through the TAB sequence or changing focus within the application, and thus cannot read the text from a TextBlock in such a mode. However, most screen readers also have modes for reading text that is not necessarily focusable. These are generally the same modes that screen readers use for a conventional non-interactive HTML document text. For example, some screen readers support a mode that reads text by line, or by word. These modes can read text from a TextBlock.

Examples

Example 1: Structure from a container that has non-semantic role in UI Automation, and TextBlock for text

If viewed as a UI Automation tree, the StackPanel and Grid do not exist explicitly in the tree view, because they do not serve a semantic role (only a presentation role). Rather, the tree consists of the items that report some kind of semantic control type. The semantic children of the containers are still reported in the order that they were declared, when viewed as children of the next semantic container upwards in the tree, and despite the containers themselves being abstracted out of the tree. This defines the reading order. This example is a large block of text with intentionally simple formatting, where the only formatting is to represent paragraphs as separate TextBlock elements to support an adaptive layout, but no Run blocks within.

When viewed with assistive technologies that represent the contents, each TextBlock is a control type of Text. Screen readers can use document reading modes such as virtual cursor modes to read the content from each element and each element's content, following the same reading order as is declared in the XAML. For example, in JAWS 12, readers can read out this text container line by line using (Jaws Key)+DownArrow. It is actually JAWS that determines the line length, because the line length otherwise is defined only by the adaptive layout at runtime, which is not reported to UIA.

  <StackPanel x:Name="LayoutRoot" Background="White">
          <TextBlock>Call me Ishmael. Some years ago--never mind how long precisely--
having little or no money in my purse, and
nothing particular to interest me on shore, I thought I would sail about a little 
and see the watery part of the world. It is a way I have of driving off the spleen 
and regulating the circulation. Whenever I find 
myself growing grim about the mouth; whenever it is a damp, drizzly November in 
my soul; whenever I find myself involuntarily pausing before coffin warehouses, 
and bringing up the rear of every funeral I meet;
and especially whenever my hypos get such an upper hand of me, that it requires a strong moral 
principle to prevent me from
deliberately stepping into the street, and methodically knocking people's hats off--then, 
I account it high time to get to sea as
soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato 
throws himself 
upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, 
almost all men in their degree, some time or other, cherish very nearly the same feelings towards the 
ocean with me.
          </TextBlock>
          <TextBlock>There now is your insular city of the Manhattoes, belted round by wharves as Indian isles 
          by coral reefs--
commerce surrounds it with her surf. Right and left, the streets take you waterward. 
Its extreme downtown is the battery, where
that noble mole is washed by waves, and cooled by breezes, which a few hours previous 
were out of sight of land. Look at the crowds of water-gazers there.
          </TextBlock>
          <TextBlock>Circumambulate the city of a dreamy Sabbath afternoon. Go from Corlears Hook 
          to Coenties Slip, and from thence, by Whitehall, northward.
What do you see?--Posted like silent sentinels all around the town, stand thousands 
upon thousands of mortal men fixed in ocean
reveries. Some leaning against the spiles; some seated upon the pier-heads; 
some looking over the bulwarks of ships from China; 
some high aloft in the rigging, as if striving to get a still better seaward peep. 
But these are all landsmen; of week days pent
up in lath and plaster--tied to counters, nailed to benches, clinched to desks. 
How  then is this? Are the green fields gone? What do they here?
          </TextBlock>
  </StackPanel>

Example 2: Text containers and their UIA representation

The following example is intended as sample XAML to view in an accessibility framework viewer, to see the various names, roles, and patterns for obtaining value.

   <StackPanel x:Name="LayoutRoot">
       <TextBox Text="This is a TextBox"/>
       <RichTextBox>
           <Paragraph>This is a RichTextBox.</Paragraph>
       </RichTextBox>
       <TextBlock Text="This is a TextBlock"/>
   </StackPanel>

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. To see UI Automation, use Microsoft Windows as platform.

  2. Use a verification tool that is capable of showing the full automation tree. (For example, use UIAVerify or Silverlight Spy; see Resources links.)

  3. Verify that TextBox elements in the Silverlight user interface have the Edit role, that RichTextBox elements have the Document role, and TextBlock has Text role in UI Automation.

  4. Verify that the text content can be programmatically determined by techniques that are appropriate for that role.

Expected Results

#3 and #4 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL33: Using Well-Formed XAML to Define a Silverlight User Interface

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL33. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the characteristics of the XAML language to support basic parsing requirements that both applications and accessibility frameworks rely upon. This technique explains the role of XAML in the overall Silverlight development and application architecture, in particular for defining the elements that make up a Silverlight user interface. This technique also present some basic facts about XAML as a language; more information of this nature is also included in Silverlight Technology Notes.

XAML is a markup language for object instantiation. XAML can be incorporated into a technology such as Silverlight. A specific XAML vocabulary can be defined by a technology such as Silverlight, and the vocabulary can be extended by anyone that provides suitable backing code. For example, a Silverlight application author can define a custom class, and the application author or potentially other Silverlight application authors can use XAML to instantiate instances of the custom class.

XAML has a published language specification.

XAML does not necessarily declare the entirety of the object tree that a Silverlight client runtime loads, but XAML typically declares the majority of the objects/elements that represent the Silverlight application's user interface. The objects and values that are used for accessibility scenarios are often closely related to the standard user interface, and thus accessibility-related properties are typically declared in XAML rather than in code, even though setting the values in code is technically possible.

For more information on XAML in Silverlight, see Silverlight XAML Overview on MSDN.

XAML and XML

XAML is based on XML, and shares many of its language features. Some of the language features that are directly relevant to the stated intent of SC4.1.1 and to 4.1.1 related techniques include:

  • Well-formedness: The definition of well-formed XAML is the same as the XML definition. XAML processors, including the Silverlight runtime XAML parser, will block loading XAML that is not well formed.

  • Duplicate attributes: Unless specially configured for scenarios such as design-time support, XAML processors will block loading XAML where elements contain duplicate attributes.

  • Quote matching: mismatched quote matching for attribute values in XAML constitutes XAML that is not well formed.

Some XAML language features that are analogous to XML but have some technology-specific differences include:

  • Identifiers: XAML defines a Name directive, which is analogous to xml:id in that Name serves as the unique identifier of an element. However, XAML defines an additional concept of a XAML namescope, which permits a XAML document to contain multiple XAML namescopes as a factoring technique. Thus, identical Name values are permitted in a XAML document so long as each is defined in a separate XAML namescope. XAML namescopes are associated with elements, such that the extent of each XAML namescope is understood by XAML processors.

  • Schemas and vocabularies: A notable difference between XAML and XML is that a XAML vocabulary is not typically represented in existing XML schema definition formats such as XSD or DTD. XAML includes inheritance and reference features that cannot adequately be expressed in XSD or other existing XML schema representation formats. This affects the "elements are nested according to their specifications" consideration of SC4.1.1. XAML definitely has the ability to enforce nesting restrictions as represented by a XAML vocabulary. However, XAML validity for a vocabulary is deliberately fluid, in order to support extension by user code. XAML validity is determined by a combination of a XAML processor, a XAML concept known as a XAML schema context, and the code that backs the XAML and defines any objects being instantiated as a parsing result. Typically, design time tools such as Microsoft Visual Studio can adequately duplicate the runtime validity characteristics of a XAML vocabulary. Using these tools, application authors can both verify XAML validity as well as receive design-time information for how to correct any XAML validity errors.

XAML parsing and HTML parsing

In the Silverlight implementation, XAML is like HTML in that it is loaded and parsed just-in-time. Silverlight XAML is not precompiled to binary or MSIL (the language-neutral CLR runtime format). Instead,Silverlight XAML is transmitted or stored as plain text, either loose or packaged as resources in a library. Thus Silverlight XAML is human readable as well as machine readable.

However, unlike HTML, Silverlight XAML is only intended to be loaded and interpreted by the Silverlight runtime, rather than multiple possible user agents that each implement an HTML engine. HTML is a language where the behavior is also specified. In contrast, XAML is a language for referencing constructs that are defined in runtime libraries, and the functional specification of the XAML language itself is minimal (intrinsics; language rules; primitive types). Layout, appearance, type-member sets, roles, etc. are all left up to specific frameworks and vocabularies that use XAML. Behavior associated with a given XAML construct is based on type definitions made in a runtime library. For Silverlight XAML, the types are from Silverlight core libraries, but often the definitions come from libraries that are available to the Silverlight runtime as part of an application's packaging for distribution.

XAML is generally speaking strict, and will raise parsing errors if XAML contains elements that are not recognized. Such parsing errors generally present the information in the XAML from resulting in any objects being created, which in turn prevents a Silverlight application from running. This is different from typical (non-xHTML) HTML, where implementations are permitted to contain nonrecognized elements or attributes and ignore them.

Examples

Example 1: XAML in design tools for Silverlight

A developer utilizes features in their Silverlight XAML authoring tool to ensure that:

  • XAML is well formed

  • XAML is valid according to Silverlight parser and all reference assemblies

  • XAML Names are unique in namescope

  • XAML has no duplicate attributes

More about design tools and XAML

Silverlight XAML is able to be loaded by design tools for Silverlight. In the design tool, the XAML is interpreted much like the runtime interprets it, in order to show the visual representation of the Silverlight application. In addition, the design tool might implement design surfaces in which the user interface can be changed, and typically provides a way to save any changes made in the tool back into the loaded XAML.

At design time, tools such as Microsoft Visual Studio or Microsoft Expression might provide opportunities to correct any XAML errors before the Silverlight application is compiled and packaged for deployment. This might be implemented by performing static analysis of the XAML, by forwarding the design tool's own parser errors as it renders the design surface, or by forwarding linking errors that are identified by a precompile step (for example, missing event handlers raise a XAML error from precompile). This behavior is sometimes identified as a design mode behavior in Microsoft documentation and other documentation about Visual Studio or specific tools.

Regardless of how a given XAML file behaves while being interacted with in a design mode, it is the Silverlight runtime XAML parser on each client installation that is the ultimate determinant of whether the XAML is valid or invalid.

Example 2: Silverlight application consumer

A consumer views a Silverlight application that is hosted in an HTML page. If the Silverlight application has valid XAML, the Silverlight content loads, and the fact that the XAML-based UI loaded at all is assurance that:

  • XAML is well formed

  • XAML is valid

  • XAML validity is partially based on correct type mapping of all elements referenced in XAML, according to Silverlight XAML parser and all reference assemblies included by that application

  • XAML Names are unique in namescope

  • XAML has no duplicate attributes

  • XAML-defined properties that are relevant for assistive technology (for example AutomationProperties.Name as described by other Silverlight techniques) are available

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Pass case

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. That application is known to consume Silverlight XAML.

  2. Verify that the application runs correctly and displays user interface.

Expected Results

#2 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.

Tests

Fail case

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. That application is known to consume Silverlight XAML, and the XAML is known to be deliberately invalid.

  2. Verify that the application did not run.

Expected Results

  1. #2 is true.

Note that it is common that an error message is displayed to users in HTML, which is implemented by handling the JavaScript OnError event emitted by the Silverlight plugin. XAML parse errors are forwarded to JavaScript errors and can be handled in this way. However, it is also possible that the application is production-ready, and deliberately does not expose any JavaScript errors, whether Silverlight managed code errors or not. If seeing the specific error is important, the test might need to be run against a preproduction or debug version of the application.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL34: Using the Silverlight Default Tab Sequence and Altering Tab Sequences With Properties

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL34. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the default Silverlight tab sequence, or alternatively to apply the options that Silverlight application authors can use for altering the tab sequence. Application authors might alter the tab sequence in cases where the default tab sequence is not desirable for some reason, and those reasons might vary per application or application scenario. The tab sequence can be altered in order to create a meaningful sequence in the tab order, so that assistive technologies that rely on traversal of focusable elements can use and determine the meaningful sequence.

Silverlight uses structured definitions for defining its user interface presentations, where the declaration order is significant because it becomes the structure of the run-time visual tree. The structured definitions also define the layout and presentation structure in most cases. The structured definition concept is described in more detail in Silverlight Technology Notes.

The Silverlight development platform attempts to create an overall system where the logical order of how elements are defined in XAML and code, and then presented in a user interface, will also match a logical tab sequence and logical reading order when presented to the user. In many cases, a Silverlight application author can write an application without necessarily worrying about the tab sequence, can test the tab sequence during a verification and testing phase of development, and will not need to set any specific properties to adjust the tab sequence. As a broad generalization, a Silverlight tab sequence will be constructed so that it traverses elements left to right, and top to bottom, and will behave similarly to how HTML would behave if the HTML analogs of Silverlight elements were constructed and presented in the same way. However, there are specific Silverlight controls that deliberately alter the tab sequence, or whose elements are made keyboard-accessible through a keyboard navigation technique other than TAB. For more information, see Focus Overview on MSDN.

How Silverlight implements tab sequence concepts

The Silverlight programming model defines a Control class that is a base class of many of the practical controls that produce a Silverlight application user interface. One of the behaviors of the Control class is that only a Control can receive keyboard focus as a discrete element within the Silverlight content area.

When a Silverlight application user interface is constructed from the visual tree, a default tab sequence for all Silverlight content is also constructed, using the same principles of order that were used by the visible layout. This default tab sequence is usually adequate as a tab sequence that supports users that press the TAB key to traverse the UI. The same TAB sequence and/or the focusable state of controls is also used by many assistive technologies or modes of assistive technologies to construct the representation of the interface for the Silverlight content.

For cases where developers decide that the default tab sequence is not adequate, the developer can take one of two approaches for changing the tab sequence:

  • Change other properties of the control where a change to the tab sequence happens as a secondary effect.

  • Reorder the tab sequence directly.

Changing control properties
  • Setting the Visibility property of a control to Collapsed causes the control to no longer render in the UI. As a secondary effect, that control is removed from the tab sequence.

  • Setting the IsEnabled property of a control to false causes the control to no longer be focusable by keyboard or clickable by the mouse. In many cases, the visual appearance of the control changes also, through a theme style. For example, the control may appear as gray rather than black. As a secondary effect, that control is removed from the tab sequence.

Changing specific tab properties
  • Setting the IsTabStop property of a control to false causes the control to no longer be focusable by keyboard or programmatic focus, and that control is removed from the tab sequence.

  • Setting the TabIndex property of a control to a specific index causes the control to be inserted at that position in the tab sequence. The default value of TabIndex is Single.MaxValue, therefore any non-default value promotes that control to be first in an otherwise default tab sequence. More typically, authors would specify a TabIndex for any controls that are involved in a deliberate segment of tab order re-ordering.

Tab order and language

Left-to-right is the default only for languages that use left-to-right reading order. For languages that use right-to-left reading order, right-to-left is also the default tab order as implemented by Silverlight runtime behavior. That language preference is declared by the acting CultureInfo. For more information on CultureInfo, see SL27: Using Language/Culture Properties as Exposed by Silverlight Applications and Assistive Technologies.

Examples

Example 1: Default tab order, based on ordering in the StackPanel

In this example, a StackPanel has a natural layout order of top-to-bottom, and that will also be the tab order of each StackPanel child element (FirstName, then LastName).

   <StackPanel x:Name="LayoutRoot" Background="White">
       <StackPanel Orientation="Horizontal">
           <TextBlock Name="lbl_FirstName">First name</TextBlock>
           <TextBox AutomationProperties.LabeledBy="{Binding ElementName=lbl_FirstName}" Name="tbFirstName" Width="100"/>
       </StackPanel>
       <StackPanel Orientation="Horizontal">
           <TextBlock Name="lbl_LastName">First name</TextBlock>
           <TextBox AutomationProperties.LabeledBy="{Binding ElementName=lbl_LastName}" Name="tbLastName" Width="100"/>
       </StackPanel>
   </StackPanel>

This example is shown in operation in the working example of Tab Sequence.

Example 2: Tab order, modified by TabIndex

A form is marked up using a data table that includes the fields of the groom in the first column and the fields of the bride in the second column. The order in the content is row by row but the author feels it is more logical for users to navigate the form column by column. This way, all the groom's criteria can be filled in before moving on to the bride's criteria. The TabIndex attributes of the Silverlight elements are used to specify a tab order that navigates column by column. This example specifically illustrates how changing tab order can change the meaningful sequence.

 <UserControl x:Class="TabSequence.MainPage"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 >
   <StackPanel x:Name="LayoutRoot" Background="White">
       <TextBlock>he first column contains the search criteria 
 of the groom, the second column the search criteria of 
 of the bride</TextBlock>
       <Grid>
       <Grid.RowDefinitions>
         <RowDefinition/>
         <RowDefinition/>
         <RowDefinition/>
         <RowDefinition/>
       </Grid.RowDefinitions>
       <Grid.ColumnDefinitions>
         <ColumnDefinition/>
         <ColumnDefinition/>
         <ColumnDefinition/>
       </Grid.ColumnDefinitions>
       <TextBlock>Search criteria</TextBlock>
       <TextBlock Grid.Column="1">Groom</TextBlock>
       <TextBlock Grid.Column="2">Bride</TextBlock>
       <TextBlock Grid.Row="1">First name</TextBlock>
       <TextBox Grid.Row="1" Grid.Column="1" TabIndex="1"/>
       <TextBox Grid.Row="1" Grid.Column="2" TabIndex="4"/>
       <TextBlock Grid.Row="2">Last name</TextBlock>
       <TextBox Grid.Row="2" Grid.Column="1" TabIndex="2"/>
       <TextBox Grid.Row="2" Grid.Column="2" TabIndex="5"/>
       <TextBlock Grid.Row="3" >Place of birth</TextBlock>
       <TextBox Grid.Row="3" Grid.Column="1" TabIndex="3"/>
       <TextBox Grid.Row="3" Grid.Column="2" TabIndex="6"/>
       </Grid>
   </StackPanel>
 </UserControl>
 

This example is shown in operation in the working example of Tab Sequence TabIndex.

Example 3: Tab order, modified by changing runtime Control properties

In this example, a radio button choice in a form controls whether certain other fields in the form are relevant or not relevant. The current radio button selection toggles the IsEnabled property in such fields to enable or disable them based on how the user selected the preceding logical element, which also affects whether the fields appear in the further tab sequence. The following is UI definition in XAML.

<UserControl x:Class="TabSequence.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
   <StackPanel x:Name="LayoutRoot" Background="White">
       <TextBlock>Registration</TextBlock>
       <Grid>
       <Grid.RowDefinitions>
         <RowDefinition/>
         <RowDefinition/>
         <RowDefinition/>
         <RowDefinition/>
       </Grid.RowDefinitions>
       <Grid.ColumnDefinitions>
         <ColumnDefinition/>
         <ColumnDefinition/>
         <ColumnDefinition/>
       </Grid.ColumnDefinitions>
           <StackPanel Orientation="Horizontal">
               <RadioButton GroupName="Registration" Checked="RadioButton_CheckedG">Guest</RadioButton>
               <RadioButton GroupName="Registration" Checked="RadioButton_CheckedC">Custom</RadioButton>
           </StackPanel>
               <TextBlock Grid.Row="1">First name</TextBlock>
           <TextBox x:Name="tb_fn" IsEnabled="false" Grid.Row="1" Grid.Column="1" />
           <TextBlock Grid.Row="2">Last name</TextBlock>
           <TextBox  x:Name="tb_ln" IsEnabled="false" Grid.Row="2" Grid.Column="1" />
       </Grid>
   </StackPanel>
</UserControl>

The following is event handler code.

       private void RadioButton_CheckedC(object sender, RoutedEventArgs e)
       {
           tb_fn.IsEnabled = true;
           tb_ln.IsEnabled = true;
       }
       private void RadioButton_CheckedG(object sender, RoutedEventArgs e)
       {
           tb_fn.IsEnabled = false;
           tb_ln.IsEnabled = false;
       }
       

This example is shown in operation in the working example of Tab Sequence Enabled.

Resources

Resources are for information purposes only, no endorsement implied.

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.

  2. Engage the screen reader. Press the TAB key to traverse the sequence of elements inside the Silverlight content area.

  3. Verify that the order in which elements are traversed in a tab sequence is also the expected order of the elements as they are presented visually, particularly in such cases where the order of each element is significant per SC 1.3.2.

Expected Results

#3 is true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.


SL35: Using the Validation and ValidationSummary APIs to Implement Client Side Forms Validation in Silverlight

Applicability

  • Microsoft Silverlight, versions 3 and greater

  • Silverlight managed programming model and Silverlight XAML

This technique relates to:

User Agent and Assistive Technology Support Notes

See User Agent Support Notes for SL35. Also see Silverlight Technology Notes.

Description

The objective of this technique is to use the Silverlight Validation API. The Validation API associates the validation logic with form input elements that properly support accessible text both for the initial entry and for any error identification and suggestion that is displayed in the user interface.

Application authors can either associate Validation.Errors output with specific UI elements, include an initially hidden ValidationSummary user interface element, or both. The example shown in this technique uses both ValidationSummary and Validation.Errors. The ValidationSummary is the most appropriate technique for providing text feedback after a form submission attempt, because assistive technologies pick it up as a discrete focusable element in the interface representation. The Validation.Errors technique is perhaps a better cognitive user experience for sighted users, because it presents the specific error suggestions in closer proximity to the input items that are in error.

This technique relies on several Silverlight features: AutomationProperties, the Name property for identifying specific UI elements, the Validation and ValidationSummary API, the ElementName variation of Silverlight data binding, and the general behavior of TextBox elements.

Contrast for validation states of the Label control

Silverlight version 4's default visual styles have a bug where the colors used to indicate an invalid field entry by changing the color of the foreground text do not satisfy the 4.5:1 contrast ratio per SC 1.4.1. To correct for this visual bug, application authors should copy the control template for the Label control, and adjust the color used for the validation state. This is shown in Example 1; the resource "LabelStyle1" was generated by copying the default Label style using Microsoft Expression Blend. Then, the value was changed in the copied template, and the changed template was referenced and included in the application. The specific changed line is indicated by a comment in the Example 1 sample markup.

Examples

Example 1: Two form fields with validation on Submit, and an error identification/suggestion system and UI on the client side

In this example, the form fields correspond to a data object that implements a view model. Silverlight uses the view model and data annotations to generate some of its UI, notably the names of the fields are bound to the original view model names from the data. The ValidationSummary API is defined in a "Client SDK" library System.Windows.Controls.Data.Input.dll, which is included as part of the project and the distributable.

This example has a UI defined in XAML and logic defined in C#. The following is the XAML UI.

<UserControl x:Class="AccessibleValidation.MainPage"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<UserControl.Resources>
 <Style x:Key="LabelStyle1" TargetType="sdk:Label">
 <Setter Property="IsTabStop" Value="False"/>
 <Setter Property="HorizontalContentAlignment" Value="Left"/>
 <Setter Property="Template">
  <Setter.Value>
   <ControlTemplate TargetType="sdk:Label">
    <Grid>
     <VisualStateManager.VisualStateGroups>
      <VisualStateGroup x:Name="CommonStates">
       <VisualState x:Name="Normal"/>
       <VisualState x:Name="Disabled"/>
      </VisualStateGroup>
      <VisualStateGroup x:Name="ValidationStates">
       <VisualState x:Name="Valid"/>
       <VisualState x:Name="Invalid">
        <Storyboard>
         <ColorAnimation Duration="0" To="#FFF00000"
         Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
         Storyboard.TargetName="ContentControl" d:IsOptimized="True"/>
         //above is the line where color was adjusted from default Red to FFF00000, 
         //to satisfy the 4.5:1 contrast requirement
        </Storyboard>
       </VisualState>
      </VisualStateGroup>
      <VisualStateGroup x:Name="RequiredStates">
       <VisualState x:Name="NotRequired"/>
       <VisualState x:Name="Required">
         <Storyboard>
          <ObjectAnimationUsingKeyFrames Duration="0" 
          Storyboard.TargetProperty="FontWeight" 
          Storyboard.TargetName="ContentControl">
           <DiscreteObjectKeyFrame KeyTime="0" Value="SemiBold"/>
          </ObjectAnimationUsingKeyFrames>
         </Storyboard>
        </VisualState>
       </VisualStateGroup>
      </VisualStateManager.VisualStateGroups>
      <Border BorderBrush="{TemplateBinding BorderBrush}" 
      BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" 
      CornerRadius="2" Padding="{TemplateBinding Padding}">
       <ContentControl x:Name="ContentControl" Cursor="{TemplateBinding Cursor}" 
         ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" 
         Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}"
         FontStretch="{TemplateBinding FontStretch}" FontSize="{TemplateBinding FontSize}" 
         FontFamily="{TemplateBinding FontFamily}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" 
         HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
         IsTabStop="False" VerticalAlignment="{TemplateBinding VerticalAlignment}" 
         VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
      </Border>
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>
</UserControl.Resources>
 <Grid x:Name="LayoutRoot" Background="White" Margin="10">
   <Grid.RowDefinitions>
     <RowDefinition Height="Auto"/>
     <RowDefinition Height="Auto"/>
     <RowDefinition Height="Auto"/>
     <RowDefinition Height="Auto"/>
     <RowDefinition Height="Auto"/>
   </Grid.RowDefinitions>
   <Grid.ColumnDefinitions>
     <ColumnDefinition Width="Auto"/>
     <ColumnDefinition Width="200"/>
     <ColumnDefinition Width="Auto"/>
   </Grid.ColumnDefinitions>
   <TextBlock Text="Validating Form" FontSize="16" FontWeight="Bold"
     Grid.Column="1" HorizontalAlignment="Center" />
   <sdk:ValidationSummary x:Name="ErrorSummary" IsTabStop="True"
     Grid.Row="1" Grid.ColumnSpan="2" Margin="3" />
   <sdk:Label x:Name="NameLabel" Target="{Binding ElementName=NameTextBox}"
     Grid.Row="2" Margin="3" HorizontalAlignment="Right" Style="{StaticResource LabelStyle1}"/>    
   <TextBox x:Name="NameTextBox" 
     AutomationProperties.Name="{Binding Content, ElementName=NameLabel}"
     Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=Explicit, 
     NotifyOnValidationError=True, ValidatesOnExceptions=True}"
     Grid.Column="1" Grid.Row="2" Margin="3" />
   <sdk:DescriptionViewer Target="{Binding ElementName=NameTextBox}" 
     Grid.Column="2" Grid.Row="2" />
   <sdk:Label x:Name="AgeLabel" Target="{Binding ElementName=AgeTextBox}"
     Grid.Row="3" Margin="3" HorizontalAlignment="Right" Style="{StaticResource LabelStyle1}"/>
   <TextBox x:Name="AgeTextBox" 
     AutomationProperties.Name="{Binding Content, ElementName=AgeLabel}" 
     Text="{Binding Age, Mode=TwoWay, UpdateSourceTrigger=Explicit, 
     NotifyOnValidationError=True, ValidatesOnExceptions=True}"  
     Grid.Column="1" Grid.Row="3" Margin="3" />
   <sdk:DescriptionViewer Target="{Binding ElementName=AgeTextBox}" 
     Grid.Column="2" Grid.Row="3" />
   <Button x:Name="SubmitButton" Content="Submit" Click="SubmitButton_Click"
     Grid.Column="1" Grid.Row="4" Width="50" Margin="3" />
 </Grid>
</UserControl>

The following is the C# logic for the page. Note the call to Focus in the logic; many assistive technologies use focus to determine what area of the interface to report to the user. If code calls Focus to reference the error summary once it is completed, the assistive technology can report the error summary immediately.

       public MainPage()
       {
           InitializeComponent();
           LayoutRoot.DataContext = new Product();
       }
       // Commits text box values when the user presses ENTER.
       private void TextBox_KeyDown(object sender, 
           System.Windows.Input.KeyEventArgs e)
       {
           if (e.Key == System.Windows.Input.Key.Enter) (sender as TextBox)
               .GetBindingExpression(TextBox.TextProperty).UpdateSource();
       }
       private void SubmitButton_Click(object sender, System.Windows.RoutedEventArgs e)
       {
           NameTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
           AgeTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
           if (ErrorSummary.Errors.Count > 0) ErrorSummary.Focus();
           }

The following is the data class. Note how much of the validation logic is defined within this view model, rather than as part of Silverlight UI logic.

  public class Product 
   {
       private string nameValue;
       private const string nameMessage = "Must be 10 characters or less.";
       [Display(Name = "Username", Description = "Required. " + nameMessage)]
       [StringLength(10, ErrorMessage = nameMessage)]
       [Required(ErrorMessage = "Required.")]
       public string Name
       {
           get { return nameValue; }
           set
           {
               if (nameValue != value)
               {
                   Validator.ValidateProperty(value, new ValidationContext(
                       this, null, null) { MemberName = "Name" });
                   nameValue = value;
               }
           }
       }
       private string ageValue;
       private const string ageMessage = "Must be in the 5 to 120 range.";
       [Display(Description = ageMessage)]
       [Range(5, 120, ErrorMessage = ageMessage)]
       [RegularExpression("\\d*", ErrorMessage = "Must be a number.")]
       public string Age
       {
           get { return ageValue; }
           set
           {
               if (ageValue != value)
               {
                   Validator.ValidateProperty(value, new ValidationContext(
                       this, null, null) { MemberName = "Age" });
                   ageValue = value;
               }
           }
       }
       

The following image is a screen shot of this simple UI, after two invalid values are entered in the form and Submit is activated:

Form with invalid values

The following image is a screen shot of the UIAVerify tree view of this same application. Note the "Text" role items that appear as adjacent peer elements, which describe the validation errors. This Text is actually coming from sdk:DescriptionViewer, and in the visible UI in the screenshot is not currently visible. This text would be visible if any of the following occurs:

  • the user hovers the mouse over the red triangle in the input field corner

  • the user hovers over the "info i" icon

  • the user clicks (or tabs to) the relevant field, which focuses it

UIAVerify tree view of form with invalid values

This example is shown in operation in the working example of Accessible Validation.

Validation style for Label controls

The default validation style for the Invalid state of Label does not have adequate contrast by default. Application authors can restyle Label with a new template that has a 4.5:1 contrast.

Resources

Tests

Procedure

  1. Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag. The application is expected to contain form fields, and a Submit pattern for form interaction as described in SL10: Implementing a Submit-Form Pattern in Silverlight.

  2. Navigate through the items of a form until an editable field is read. Enter a value that triggers the validation.

  3. Navigate to Submit button and activate it to attempt to submit the form.

  4. Verify that a Validation Summary now appears, and is focusable.

  5. Verify that the Validation Summary provides enough information to correct any error.

  6. Navigate back to input elements that have validation issues. Correct the errors as suggested.

  7. Tab to Submit button. Press ENTER to resubmit.

  8. Verify that Validation Summary is no longer displayed and that the screen reader does not focus to/read any further validation information.

Expected Results

#4, #5, and #8 are true.

If this is a sufficient technique for a success criterion, failing this test procedure does not necessarily mean that the success criterion has not been satisfied in some other way, only that this technique has not been successfully implemented and can not be used to claim conformance.