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.
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.
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:
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).
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.
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.
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.
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:
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.
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 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.
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.
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)
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.
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
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.
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.
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.
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.
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.
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.
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.
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:
Click the link from the technique to download the ZIP file.
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.
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.
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.
Once the content is in view, follow the remaining steps that are indicated in the specific test procedure.
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.
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.
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.
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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL1. Also see Silverlight Technology Notes.
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.
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.
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 are for information purposes only, no endorsement implied.
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.
Verify that the application user interface presents a control that enables the user to cause the media to play with an alternate audio track.
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL2. Also see Silverlight Technology Notes.
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 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:
The user uses the Silverlight tab sequence to traverse into the Silverlight content and to focus a specific control.
The Silverlight application's logic calls the Focus
method
programmatically to force focus to a control.
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.
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.
This example is shown in operation in the working example of Visible Focus Template.
Resources are for information purposes only, no endorsement implied.
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.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
Using a keyboard, tab to the element where focus characteristics are being examined.
Check that the background, border, or other noticable visual indicator of the element changes color.
Check that the changes in color for the background, border, or other noticable visual indicator are removed when the element loses focus.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL3. Also see Silverlight Technology Notes.
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.
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 are for information purposes only, no endorsement implied.
Silverlight
Media Framework - a framework and a media player control implementation
that incorporates many of the Silverlight techniques related to MediaElement
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
.
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.
Check that control is available for muting, and that the Mute control mutes the volume of the playing media, independently from system volume.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL4. Also see Silverlight Technology Notes.
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.
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.
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references multiple Silverlight object tags, each with different HTML Lang values.
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL5. Also see Silverlight Technology Notes.
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.
The two examples are intended to be used together, if an application is both defining and consuming the focusable image control.
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.
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 are for information purposes only, no endorsement implied.
Open the test HTML page in a Silverlight-supported useragent host; to use UI Automation, use Microsoft Windows as platform.
Use the tab sequence inside the Silverlight content area to focus the control.
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.
#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.
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.
Engage the screen reader. Move focus to the control (for example, use the tab sequence).
Check that the Name
applied to the image is read
by the screen reader.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL6. Also see Silverlight Technology Notes.
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.
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 are for information purposes only, no endorsement implied.
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.
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.
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.
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).
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL7. Also see Silverlight Technology Notes.
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.
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.
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.
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 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:
The user uses the Silverlight tab sequence to traverse into the Silverlight content and to focus a specific control.
The Silverlight application's logic calls the Focus() method programmatically to force focus to a control.
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.
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
Using a keyboard, tab to the element where focus characteristics are being examined.
Check that the background, border, or other noticable visual indicator of the element changes color.
Check that the changes in color for the background, border, or other noticable visual indicator are removed when the element loses focus.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL8. Also see Silverlight Technology Notes.
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.
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.
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();
}
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
After activating Get Help
This example is shown in operation in the working example of HelpText and Tooltip.
Resources are for information purposes only, no endorsement implied.
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.
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.
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.
If using a screen reader, verify that the long text alternative can be read aloud.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL9. Also see Silverlight Technology Notes.
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,
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.
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.
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.
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.
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.
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
Press TAB key to move keyboard focus to various element parts of the user interface.
Verify that any user interface actions that exist for a given element part each have a keyboard equivalent.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL10. Also see Silverlight Technology Notes.
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.
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.
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 are for information purposes only, no endorsement implied.
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.
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).
Provide values for the various input fields of the form, and verify that doing so does not in and of itself change the context.
Verify that if change of context occurs at all, that action is delayed until after the Submit button is activated.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL11. Also see Silverlight Technology Notes.
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.
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.
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 are for information purposes only, no endorsement implied.
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:
Check for a mechanism to stop the movement, blinking, scrolling or auto-updating.
Check that the movement, blinking, scrolling or auto-updating stops when the mechanism is activated and does not restart by itself.
For pause, check that the animation can be restarted using a start mechanism.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL12. Also see Silverlight Technology Notes.
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.
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 are for information purposes only, no endorsement implied.
Silverlight
Media Framework - a framework and a media player control implementation
that incorporates many of the Silverlight techniques related to MediaElement
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.
Check that interactive controls are available so that users can pause or stop the media.
Check that when activated, the controls stop or pause the media.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL13. Also see Silverlight Technology Notes.
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.
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).
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 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.
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.
This example is shown in operation in the working example of High Contrast.
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 are for information purposes only, no endorsement implied.
To test a Silverlight UI option for style switching (Example 1):
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
Check for a control that indicates it will change the application's appearance to use a high-contrast theme.
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)).
#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.
To test the HighContrast API (Example 2):
Use operating system settings (such as Ctrl+LeftShift+PrtScn shortcut on Windows 7) to enter high contrast mode prior to opening the test page.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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)).
#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.
To test a Silverlight UI option for style switching for enhanced contrast:
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
Check for a control that indicates it will change the application's appearance to use an enhanced contrast theme.
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).
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL14. Also see Silverlight Technology Notes.
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.
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.
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.
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.
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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.
Check that custom key commands exist for all these user interface actions and that these key commands are made known to the user.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL15. Also see Silverlight Technology Notes.
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:
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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.
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.
Verify that pressing the application-specific keys results in the action as expected in the application.
Move keyboard focus throughout other areas of the Silverlight application, and verify that the same keys continue to function application-wide.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL16. Also see Silverlight Technology Notes.
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.
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
.
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 are for information purposes only, no endorsement implied.
Accessible Media Project - a reference implementation MediaPlayer control from the Silverlight product team that includes several accessibility features including captioning; note that the codebase might not be updated to Silverlight version 4
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.
Check that a text area in the user interface shows captions for the media.
# 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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL17. Also see Silverlight Technology Notes.
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.
If the media being played is audio-only, and the alternative content is a text equivalent such as a transcript, this technique addresses Success Criterion 1.2.1 (Audio-only and Video-only, Prerecorded).
If the media includes content that cannot be adequately described by either alternative audio track or additional text captions, and the best alternative is to provide a full description in text such as a screenplay of the content, this technique addresses Success Criterion 1.2.3 (Audio Description or Full Text Alternative) and is similar to G69: Providing an alternative for time based media.
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.
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 are for information purposes only, no endorsement implied.
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.
Check for a control that indicates that activating it will supply static alternative content for the media. Activate the control.
Verify that the media control is replaced with alternate content, and that assistive technologies represent the change to the user interface.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL18. Also see Silverlight Technology Notes.
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).
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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.
#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.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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.
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL19. Also see Silverlight Technology Notes.
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.
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.”/>
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 are for information purposes only, no endorsement implied.
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.
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.)
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL20. Also see Silverlight Technology Notes.
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.
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.
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".
This example is shown in operation in the working example of Simple Peer Forwarding.
Resources are for information purposes only, no endorsement implied.
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.
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.)
Check that any element where default automation peer promotion is expected is supplying a default Name in the automation tree.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL21. Also see Silverlight Technology Notes.
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.
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 are for information purposes only, no endorsement implied.
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:
Check for a mechanism to stop the time limit on interaction.
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.
#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.
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:
See User Agent Support Notes for SL22. Also see Silverlight Technology Notes.
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.
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.
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.
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 are for information purposes only, no endorsement implied.
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.
Verify that the Silverlight application enables auto zoom (no Silverlight application-specific code or markup has set EnableAutoZoom API to false).
Test the zooming feature of the user agent. Verify that browser zoom factors apply to the Silverlight content.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL23. Also see Silverlight Technology Notes.
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).
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.
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.
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.
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.
This example is shown in operation in the working example of Style Switcher Font Size.
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
Verify that the application provides a control that can increase font size.
Activate the control, and check that the font sizes increase.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL24. Also see Silverlight Technology Notes.
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.
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 are for information purposes only, no endorsement implied.
Silverlight
Media Framework - a framework and a media player control implementation
that incorporates many of the Silverlight techniques related to MediaElement
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.
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL25. Also see Silverlight Technology Notes.
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.
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.
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 are for information purposes only, no endorsement implied.
Open the test HTML page for a Silverlight application.
Check for a control that indicates that activating that control can skip to some particular region of the content.
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL26. Also see Silverlight Technology Notes.
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.
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.
<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 are for information purposes only, no endorsement implied.
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.
Use a verification tool that is capable of showing the full automation tree. (For example, use UIAVerify or Silverlight Spy; see Resources links.)
Verify that any element that has a LabeledBy
value
has an associated visible label.
Verify that any element that has a LabeledBy
value
uses the Name
value from that label.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL27. Also see Silverlight Technology Notes.
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.
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).
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
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.
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.
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.
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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).
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL28. Also see Silverlight Technology Notes.
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
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.
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.
From the initial Expression Encoder screen, select New Project from the File menu.
In the Load a new project dialog, select Silverlight Project.
From the File menu, select Import. Choose the primary media source file the project will use.
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.
Choose a timed text file to add to the project.
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.
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.
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 are for information purposes only, no endorsement implied.
Accessible Media Project - a reference implementation MediaPlayer control from the Silverlight product team that includes several accessibility features including captioning; note that the codebase might not be updated to Silverlight version 4
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.
Check that the text area in the textbox shows captions for the media, and that the captions synchronize with media in an expected way.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL29. Also see Silverlight Technology Notes.
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.
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:
This example is shown in operation in the working example of Tab Navigation.
Resources are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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).
Verify that the list children are still accessible by keyboard, by using ARROW keys rather than TAB.
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.
Use a screen reader to verify that name and role are reported properly.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL30. Also see Silverlight Technology Notes.
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.
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.
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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.)
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.
#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.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
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.
Check that the Name
as applied to the control
instance, along with the class name of the control, is read by the
screen reader.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL31. Also see Silverlight Technology Notes.
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.
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.
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.
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="http://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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
Test that application of font properties as enabled in application UI changes presentation, but does not change semantic meaning of text.
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL32. Also see Silverlight Technology Notes.
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:
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.
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.
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.
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
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
.
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>
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 are for information purposes only, no endorsement implied.
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.
Use a verification tool that is capable of showing the full automation tree. (For example, use UIAVerify or Silverlight Spy; see Resources links.)
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.
Verify that the text content can be programmatically determined by techniques that are appropriate for that role.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL33. Also see Silverlight Technology Notes.
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 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.
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.
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
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.
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 are for information purposes only, no endorsement implied.
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.
Verify that the application runs correctly and displays user interface.
#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.
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.
Verify that the application did not run.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL34. Also see Silverlight Technology Notes.
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.
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.
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.
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.
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.
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.
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.
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 are for information purposes only, no endorsement implied.
Using a browser that supports Silverlight, open an HTML page that references a Silverlight application through an object tag.
Engage the screen reader. Press the TAB key to traverse the sequence of elements inside the Silverlight content area.
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.
#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.
Microsoft Silverlight, versions 3 and greater
Silverlight managed programming model and Silverlight XAML
This technique relates to:
See User Agent Support Notes for SL35. Also see Silverlight Technology Notes.
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.
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.
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:
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
This example is shown in operation in the working example of Accessible Validation.
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 are for information purposes only, no endorsement implied.
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.
Navigate through the items of a form until an editable field is read. Enter a value that triggers the validation.
Navigate to Submit button and activate it to attempt to submit the form.
Verify that a Validation Summary now appears, and is focusable.
Verify that the Validation Summary provides enough information to correct any error.
Navigate back to input elements that have validation issues. Correct the errors as suggested.
Tab to Submit button. Press ENTER to resubmit.
Verify that Validation Summary is no longer displayed and that the screen reader does not focus to/read any further validation information.
#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.