summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.WinRT
diff options
context:
space:
mode:
authorSamantha Houts <samantha@teamredwall.com>2017-01-31 11:49:15 -0800
committerKangho Hur <kangho.hur@samsung.com>2017-03-24 13:16:43 +0900
commit330f236a9e0c87b7e7ea2047e077b16df2e9b4d3 (patch)
tree4d33bfe5f705cdeb9b3c91f039805b976c35027f /Xamarin.Forms.Platform.WinRT
parentb362c49113b331280cc4f8c7e70fef3e52e07e37 (diff)
downloadxamarin-forms-330f236a9e0c87b7e7ea2047e077b16df2e9b4d3.tar.gz
xamarin-forms-330f236a9e0c87b7e7ea2047e077b16df2e9b4d3.tar.bz2
xamarin-forms-330f236a9e0c87b7e7ea2047e077b16df2e9b4d3.zip
[All] Basic Accessibility Support (#713)
* [Core] Add accessibility properties * [Controls] Add accessibility gallery * [iOS] Implement accessibility properties * [Android] Implement accessibilty properties * [Win] Implement accessibility properties * [Win] Select ListView item on selected for a11y * Update docs * TODO: macOS accessibility * [iOS] Fix failing UI Tests
Diffstat (limited to 'Xamarin.Forms.Platform.WinRT')
-rw-r--r--Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs5
-rw-r--r--Xamarin.Forms.Platform.WinRT/IVisualElementRenderer.cs3
-rw-r--r--Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs28
-rw-r--r--Xamarin.Forms.Platform.WinRT/MasterDetailPageRenderer.cs5
-rw-r--r--Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs5
-rw-r--r--Xamarin.Forms.Platform.WinRT/ViewRenderer.cs98
-rw-r--r--Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs91
7 files changed, 220 insertions, 15 deletions
diff --git a/Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs b/Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs
index 11f4e09d..33e09399 100644
--- a/Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs
@@ -70,6 +70,11 @@ namespace Xamarin.Forms.Platform.WinRT
return new SizeRequest(result);
}
+ UIElement IVisualElementRenderer.GetNativeElement()
+ {
+ return null;
+ }
+
public void SetElement(VisualElement element)
{
var newPage = element as CarouselPage;
diff --git a/Xamarin.Forms.Platform.WinRT/IVisualElementRenderer.cs b/Xamarin.Forms.Platform.WinRT/IVisualElementRenderer.cs
index 4db9c1a6..abae812e 100644
--- a/Xamarin.Forms.Platform.WinRT/IVisualElementRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/IVisualElementRenderer.cs
@@ -18,6 +18,9 @@ namespace Xamarin.Forms.Platform.WinRT
event EventHandler<VisualElementChangedEventArgs> ElementChanged;
SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint);
+
void SetElement(VisualElement element);
+
+ UIElement GetNativeElement();
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs b/Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs
index db581d52..031e2cf3 100644
--- a/Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs
@@ -77,9 +77,6 @@ namespace Xamarin.Forms.Platform.WinRT
// and prevented from bubbling up) rather than ListView.ItemClick
List.Tapped += ListOnTapped;
- // We also want to watch for the Enter key being pressed for selection
- List.KeyUp += OnKeyPressed;
-
List.SelectionChanged += OnControlSelectionChanged;
List.SetBinding(ItemsControl.ItemsSourceProperty, "");
@@ -141,7 +138,6 @@ namespace Xamarin.Forms.Platform.WinRT
if (List != null)
{
List.Tapped -= ListOnTapped;
- List.KeyUp -= OnKeyPressed;
List.SelectionChanged -= OnControlSelectionChanged;
@@ -508,17 +504,6 @@ namespace Xamarin.Forms.Platform.WinRT
#endif
}
- void OnKeyPressed(object sender, KeyRoutedEventArgs e)
- {
- if (e.Key == VirtualKey.Enter)
- {
- if (Element.SelectedItem != null && Element.SelectedItem != List.SelectedItem)
- {
- ((IElementController)Element).SetValueFromRenderer(ListView.SelectedItemProperty, List.SelectedItem);
- }
- }
- }
-
void OnControlSelectionChanged(object sender, SelectionChangedEventArgs e)
{
RestorePreviousSelectedVisual();
@@ -540,6 +525,10 @@ namespace Xamarin.Forms.Platform.WinRT
}
}
#endif
+
+ // A11y: Tapped event will not be routed when Narrator is active
+ // Also handles keyboard selection
+ SelectElementItem();
}
FrameworkElement FindElement(object cell)
@@ -553,6 +542,15 @@ namespace Xamarin.Forms.Platform.WinRT
return null;
}
+ void SelectElementItem()
+ {
+ if (List.SelectedItem != null && Element.SelectedItem != List.SelectedItem)
+ {
+ ((IElementController)Element).SetValueFromRenderer(ListView.SelectedItemProperty, List?.SelectedItem);
+ OnElementItemSelected(null, new SelectedItemChangedEventArgs(Element?.SelectedItem));
+ }
+ }
+
#if WINDOWS_UWP
void RestorePreviousSelectedVisual()
{
diff --git a/Xamarin.Forms.Platform.WinRT/MasterDetailPageRenderer.cs b/Xamarin.Forms.Platform.WinRT/MasterDetailPageRenderer.cs
index 414870cd..dcef680e 100644
--- a/Xamarin.Forms.Platform.WinRT/MasterDetailPageRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/MasterDetailPageRenderer.cs
@@ -94,6 +94,11 @@ namespace Xamarin.Forms.Platform.WinRT
public event EventHandler<VisualElementChangedEventArgs> ElementChanged;
+ UIElement IVisualElementRenderer.GetNativeElement()
+ {
+ return null;
+ }
+
public SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint)
{
return new SizeRequest(new Size(Device.Info.ScaledScreenSize.Width, Device.Info.ScaledScreenSize.Height));
diff --git a/Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs b/Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs
index e7e01843..5229fdcb 100644
--- a/Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs
@@ -137,6 +137,11 @@ namespace Xamarin.Forms.Platform.WinRT
return new SizeRequest(result);
}
+ UIElement IVisualElementRenderer.GetNativeElement()
+ {
+ return null;
+ }
+
public void SetElement(VisualElement element)
{
if (element != null && !(element is NavigationPage))
diff --git a/Xamarin.Forms.Platform.WinRT/ViewRenderer.cs b/Xamarin.Forms.Platform.WinRT/ViewRenderer.cs
index 148da1b3..0017531f 100644
--- a/Xamarin.Forms.Platform.WinRT/ViewRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/ViewRenderer.cs
@@ -1,5 +1,6 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Automation;
+using Windows.UI.Xaml.Automation.Peers;
#if WINDOWS_UWP
@@ -11,6 +12,11 @@ namespace Xamarin.Forms.Platform.WinRT
{
public class ViewRenderer<TElement, TNativeElement> : VisualElementRenderer<TElement, TNativeElement> where TElement : View where TNativeElement : FrameworkElement
{
+ string _defaultAutomationPropertiesName;
+ AccessibilityView? _defaultAutomationPropertiesAccessibilityView;
+ string _defaultAutomationPropertiesHelpText;
+ UIElement _defaultAutomationPropertiesLabeledBy;
+
protected override void OnElementChanged(ElementChangedEventArgs<TElement> e)
{
base.OnElementChanged(e);
@@ -33,5 +39,97 @@ namespace Xamarin.Forms.Platform.WinRT
Control.SetValue(AutomationProperties.AutomationIdProperty, id);
}
}
+ protected override void SetAutomationPropertiesName()
+ {
+ if (Control == null)
+ {
+ base.SetAutomationPropertiesName();
+ return;
+ }
+
+ if (Element == null)
+ return;
+
+ if (_defaultAutomationPropertiesName == null)
+ _defaultAutomationPropertiesName = (string)Control.GetValue(AutomationProperties.NameProperty);
+
+ var elemValue = (string)Element.GetValue(Accessibility.NameProperty);
+
+ if (!string.IsNullOrWhiteSpace(elemValue))
+ Control.SetValue(AutomationProperties.NameProperty, elemValue);
+ else
+ Control.SetValue(AutomationProperties.NameProperty, _defaultAutomationPropertiesName);
+ }
+
+ protected override void SetAutomationPropertiesAccessibilityView()
+ {
+ if (Control == null)
+ {
+ base.SetAutomationPropertiesAccessibilityView();
+ return;
+ }
+
+ if (Element == null)
+ return;
+
+ if (!_defaultAutomationPropertiesAccessibilityView.HasValue)
+ _defaultAutomationPropertiesAccessibilityView = (AccessibilityView)Control.GetValue(AutomationProperties.AccessibilityViewProperty);
+
+ var newValue = _defaultAutomationPropertiesAccessibilityView;
+ var elemValue = (bool?)Element.GetValue(Accessibility.IsInAccessibleTreeProperty);
+
+ if (elemValue == true)
+ newValue = AccessibilityView.Content;
+ else if (elemValue == false)
+ newValue = AccessibilityView.Raw;
+
+ Control.SetValue(AutomationProperties.AccessibilityViewProperty, newValue);
+ }
+
+ protected override void SetAutomationPropertiesHelpText()
+ {
+ if (Control == null)
+ {
+ base.SetAutomationPropertiesHelpText();
+ return;
+ }
+
+ if (Element == null)
+ return;
+
+ if (_defaultAutomationPropertiesHelpText == null)
+ _defaultAutomationPropertiesHelpText = (string)Control.GetValue(AutomationProperties.HelpTextProperty);
+
+ var elemValue = (string)Element.GetValue(Accessibility.HintProperty);
+
+ if (!string.IsNullOrWhiteSpace(elemValue))
+ Control.SetValue(AutomationProperties.HelpTextProperty, elemValue);
+ else
+ Control.SetValue(AutomationProperties.HelpTextProperty, _defaultAutomationPropertiesHelpText);
+ }
+
+ protected override void SetAutomationPropertiesLabeledBy()
+ {
+ if (Control == null)
+ {
+ base.SetAutomationPropertiesLabeledBy();
+ return;
+ }
+
+ if (Element == null)
+ return;
+
+ if (_defaultAutomationPropertiesLabeledBy == null)
+ _defaultAutomationPropertiesLabeledBy = (UIElement)Control.GetValue(AutomationProperties.LabeledByProperty);
+
+ var elemValue = (VisualElement)Element.GetValue(Accessibility.LabeledByProperty);
+ var renderer = elemValue?.GetOrCreateRenderer();
+ var nativeElement = renderer?.GetNativeElement();
+
+ if (nativeElement != null)
+ Control.SetValue(AutomationProperties.LabeledByProperty, nativeElement);
+ else
+ Control.SetValue(AutomationProperties.LabeledByProperty, _defaultAutomationPropertiesLabeledBy);
+ }
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs b/Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs
index b81f73e3..402d1da8 100644
--- a/Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/VisualElementRenderer.cs
@@ -4,6 +4,7 @@ using System.ComponentModel;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Automation;
+using Windows.UI.Xaml.Automation.Peers;
using Windows.UI.Xaml.Controls;
#if WINDOWS_UWP
@@ -17,6 +18,10 @@ namespace Xamarin.Forms.Platform.WinRT
public class VisualElementRenderer<TElement, TNativeElement> : Panel, IVisualElementRenderer, IDisposable, IEffectControlProvider where TElement : VisualElement
where TNativeElement : FrameworkElement
{
+ string _defaultAutomationPropertiesName;
+ AccessibilityView? _defaultAutomationPropertiesAccessibilityView;
+ string _defaultAutomationPropertiesHelpText;
+ UIElement _defaultAutomationPropertiesLabeledBy;
bool _disposed;
EventHandler<VisualElementChangedEventArgs> _elementChangedHandlers;
VisualElementTracker<TElement, TNativeElement> _tracker;
@@ -108,6 +113,11 @@ namespace Xamarin.Forms.Platform.WinRT
return new SizeRequest(result);
}
+ public UIElement GetNativeElement()
+ {
+ return Control;
+ }
+
public void SetElement(VisualElement element)
{
TElement oldElement = Element;
@@ -287,6 +297,14 @@ namespace Xamarin.Forms.Platform.WinRT
UpdateEnabled();
else if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
UpdateBackgroundColor();
+ else if (e.PropertyName == Accessibility.HintProperty.PropertyName)
+ SetAutomationPropertiesHelpText();
+ else if (e.PropertyName == Accessibility.NameProperty.PropertyName)
+ SetAutomationPropertiesName();
+ else if (e.PropertyName == Accessibility.IsInAccessibleTreeProperty.PropertyName)
+ SetAutomationPropertiesAccessibilityView();
+ else if (e.PropertyName == Accessibility.LabeledByProperty.PropertyName)
+ SetAutomationPropertiesLabeledBy();
}
protected virtual void OnRegisterEffect(PlatformEffect effect)
@@ -300,6 +318,75 @@ namespace Xamarin.Forms.Platform.WinRT
SetValue(AutomationProperties.AutomationIdProperty, id);
}
+ protected virtual void SetAutomationPropertiesName()
+ {
+ if (Element == null || Control == null)
+ return;
+
+ if (_defaultAutomationPropertiesName == null)
+ _defaultAutomationPropertiesName = (string)Control.GetValue(AutomationProperties.NameProperty);
+
+ var elemValue = (string)Element.GetValue(Accessibility.NameProperty);
+
+ if (!string.IsNullOrWhiteSpace(elemValue))
+ Control.SetValue(AutomationProperties.NameProperty, elemValue);
+ else
+ Control.SetValue(AutomationProperties.NameProperty, _defaultAutomationPropertiesName);
+ }
+
+ protected virtual void SetAutomationPropertiesAccessibilityView()
+ {
+ if (Element == null || Control == null)
+ return;
+
+ if (!_defaultAutomationPropertiesAccessibilityView.HasValue)
+ _defaultAutomationPropertiesAccessibilityView = (AccessibilityView)Control.GetValue(AutomationProperties.AccessibilityViewProperty);
+
+ var newValue = _defaultAutomationPropertiesAccessibilityView;
+ var elemValue = (bool?)Element.GetValue(Accessibility.IsInAccessibleTreeProperty);
+
+ if (elemValue == true)
+ newValue = AccessibilityView.Content;
+ else if (elemValue == false)
+ newValue = AccessibilityView.Raw;
+
+ Control.SetValue(AutomationProperties.AccessibilityViewProperty, newValue);
+ }
+
+ protected virtual void SetAutomationPropertiesHelpText()
+ {
+ if (Element == null || Control == null)
+ return;
+
+ if (_defaultAutomationPropertiesHelpText == null)
+ _defaultAutomationPropertiesHelpText = (string)Control.GetValue(AutomationProperties.HelpTextProperty);
+
+ var elemValue = (string)Element.GetValue(Accessibility.HintProperty);
+
+ if (!string.IsNullOrWhiteSpace(elemValue))
+ Control.SetValue(AutomationProperties.HelpTextProperty, elemValue);
+ else
+ Control.SetValue(AutomationProperties.HelpTextProperty, _defaultAutomationPropertiesHelpText);
+ }
+
+ protected virtual void SetAutomationPropertiesLabeledBy()
+ {
+ if (Element == null || Control == null)
+ return;
+
+ if (_defaultAutomationPropertiesLabeledBy == null)
+ _defaultAutomationPropertiesLabeledBy = (UIElement)Control.GetValue(AutomationProperties.LabeledByProperty);
+
+ var elemValue = (VisualElement)Element.GetValue(Accessibility.LabeledByProperty);
+ var renderer = elemValue?.GetOrCreateRenderer();
+ var nativeElement = renderer?.GetNativeElement();
+
+ if (nativeElement != null)
+ Control.SetValue(AutomationProperties.LabeledByProperty, nativeElement);
+ else
+ Control.SetValue(AutomationProperties.LabeledByProperty, _defaultAutomationPropertiesLabeledBy);
+ }
+
protected void SetNativeControl(TNativeElement control)
{
TNativeElement oldControl = Control;
@@ -367,6 +454,10 @@ namespace Xamarin.Forms.Platform.WinRT
protected virtual void UpdateNativeControl()
{
UpdateEnabled();
+ SetAutomationPropertiesHelpText();
+ SetAutomationPropertiesName();
+ SetAutomationPropertiesAccessibilityView();
+ SetAutomationPropertiesLabeledBy();
}
internal virtual void OnElementFocusChangeRequested(object sender, VisualElement.FocusRequestArgs args)