Skip to content

Commit

Permalink
Approach — How to send and resend accessibility focus
Browse files Browse the repository at this point in the history
  • Loading branch information
JTOne123 committed Aug 31, 2021
1 parent 680c223 commit c0d8784
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 13 deletions.
2 changes: 1 addition & 1 deletion A11YTools/A11YTools.Android/AndroidA11yService.cs
Expand Up @@ -65,7 +65,7 @@ public void SetFocus(VisualElement element)
var renderer = Platform.GetRenderer(element);
var view = element.GetViewForAccessibility();

view?.SendAccessibilityEvent(EventTypes.ViewAccessibilityFocused);
view?.SendAccessibilityEvent(EventTypes.ViewFocused);
}

public void SetAnnouncement(string text)
Expand Down
7 changes: 7 additions & 0 deletions A11YTools/A11YTools.UWP/A11YTools.UWP.csproj
Expand Up @@ -90,6 +90,7 @@
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<ItemGroup>
<Compile Include="AccessibleFocusBlockRenderer.cs" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
Expand All @@ -98,6 +99,7 @@
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SemanticViewRenderer.cs" />
<Compile Include="UWPA11yService.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
Expand Down Expand Up @@ -162,4 +164,9 @@
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties XamarinHotReloadXFormsNugetUpgradeInfoBarA11YToolsUWPHideInfoBar="True" />
</VisualStudio>
</ProjectExtensions>
</Project>
86 changes: 86 additions & 0 deletions A11YTools/A11YTools.UWP/AccessibleFocusBlockRenderer.cs
@@ -0,0 +1,86 @@
using A11YTools.UWP;
using A11YTools.Views;
using System.ComponentModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Xamarin.Forms.Platform.UWP;

[assembly: ExportRenderer(typeof(AccessibleFocusBlock), typeof(AccessibleFocusBlockRenderer))]
namespace A11YTools.UWP
{
public class AccessibleFocusBlockRenderer : ViewRenderer<AccessibleFocusBlock, Windows.UI.Xaml.Controls.Button>
{
private Windows.UI.Xaml.Controls.Button accessibilityHiddenBtn = null;

protected override void OnElementChanged(ElementChangedEventArgs<AccessibleFocusBlock> e)
{
base.OnElementChanged(e);

if (e.OldElement != null && accessibilityHiddenBtn != null)
{
accessibilityHiddenBtn.Click -= AccessibilityHiddenBtn_Click;
accessibilityHiddenBtn.GotFocus -= AccessibilityHiddenBtn_GotFocus;
accessibilityHiddenBtn.LostFocus -= AccessibilityHiddenBtn_LostFocus;
accessibilityHiddenBtn = null;

SetNativeControl(null);
}

if (e.NewElement != null)
{
accessibilityHiddenBtn = new Windows.UI.Xaml.Controls.Button();
accessibilityHiddenBtn.IsTabStop = e.NewElement.IsTabStop;
accessibilityHiddenBtn.IsHitTestVisible = false;
accessibilityHiddenBtn.IsEnabled = e.NewElement.IsEnabled;
accessibilityHiddenBtn.Visibility = e.NewElement.IsTabStop && e.NewElement.IsEnabled && e.NewElement.IsVisible ? Visibility.Visible : Visibility.Collapsed;
accessibilityHiddenBtn.UseSystemFocusVisuals = false;
accessibilityHiddenBtn.Click += AccessibilityHiddenBtn_Click;
accessibilityHiddenBtn.GotFocus += AccessibilityHiddenBtn_GotFocus;
accessibilityHiddenBtn.LostFocus += AccessibilityHiddenBtn_LostFocus;
Canvas.SetZIndex(accessibilityHiddenBtn, -1);

SetNativeControl(accessibilityHiddenBtn);
}
}

protected override void Dispose(bool disposing)
{
if (disposing && Control != null)
{
accessibilityHiddenBtn.Click -= AccessibilityHiddenBtn_Click;
accessibilityHiddenBtn.GotFocus -= AccessibilityHiddenBtn_GotFocus;
accessibilityHiddenBtn.LostFocus -= AccessibilityHiddenBtn_LostFocus;
accessibilityHiddenBtn = null;

SetNativeControl(null);
}
base.Dispose(disposing);
}

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);

switch (e.PropertyName)
{
case nameof(Element.IsEnabled):
case nameof(Element.IsTabStop):
case nameof(Element.IsVisible):
accessibilityHiddenBtn.Visibility = Element.IsTabStop && Element.IsEnabled && Element.IsVisible ? Visibility.Visible : Visibility.Collapsed;
break;
}
}

private void AccessibilityHiddenBtn_GotFocus(object sender, RoutedEventArgs e)
{
}

private void AccessibilityHiddenBtn_LostFocus(object sender, RoutedEventArgs e)
{
}

private void AccessibilityHiddenBtn_Click(object sender, RoutedEventArgs e)
{
}
}
}
52 changes: 52 additions & 0 deletions A11YTools/A11YTools.UWP/UWPA11yService.cs
@@ -0,0 +1,52 @@
using A11YTools.UWP;
using A11YTools.Views;
using System;
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;

[assembly: Dependency(typeof(UWPA11yService))]
namespace A11YTools.UWP
{
public class UWPA11yService : IA11yService
{
public void SetAnnouncement(string text)
{
throw new NotImplementedException();
}

public void SetControlType(VisualElement element, ControlType controlType)
{
throw new NotImplementedException();
}

public async void SetFocus(VisualElement element)
{
var containerElement = Platform.GetRenderer(element).ContainerElement;

FrameworkElement view = null;
if (containerElement is AccessibleFocusBlockRenderer)
{
view = ((Xamarin.Forms.Platform.UWP.VisualElementRenderer<A11YTools.Views.AccessibleFocusBlock, Windows.UI.Xaml.Controls.Button>)containerElement).Control;
}
if (containerElement is ButtonRenderer)
{
view = ((VisualElementRenderer<Xamarin.Forms.Button, Xamarin.Forms.Platform.UWP.FormsButton>)containerElement).Control;
}

if (view == null)
throw new NotImplementedException();

var result = await FocusManager.TryFocusAsync(view, FocusState.Programmatic);

Debug.WriteLine($"Set focus result {result.Succeeded}");
}

public void SetIsClickable(VisualElement element, bool isClickable, Action clickActionThatOnlyRunsOnAndroid)
{
throw new NotImplementedException();
}
}
}
8 changes: 8 additions & 0 deletions A11YTools/A11YTools/Views/AccessibleFocusBlock.cs
@@ -0,0 +1,8 @@
using Xamarin.Forms;

namespace A11YTools.Views
{
public class AccessibleFocusBlock : ContentView
{
}
}
44 changes: 37 additions & 7 deletions A11YTools/A11YTools/Views/SetFocus.xaml
@@ -1,15 +1,45 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="A11YTools.Views.SetFocus">
x:Class="A11YTools.Views.SetFocus"
xmlns:local="clr-namespace:A11YTools.Views">
<ContentPage.Content>

<StackLayout>
<Label x:Name="theLabel" Text="Hello I am the Label"></Label>
<Button
Text="Set Accessibility Focus To Label"
Clicked="Button_Clicked"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />

<local:AccessibleFocusBlock x:Name="afcLabel"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.LabeledBy="{x:Reference theLabel}">
<Label x:Name="theLabel"
Text="Hello I am the Label" />
</local:AccessibleFocusBlock>

<local:AccessibleFocusBlock x:Name="afcLabel2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.LabeledBy="{x:Reference theLabel2}">
<Label x:Name="theLabel2"
Text="Hello I am the Label 2" />
</local:AccessibleFocusBlock>

<Button x:Name="theButton1"
Text="Set Accessibility Focus To Label"
Clicked="Button_Clicked"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />

<Button x:Name="theButton2"
Text="Set Accessibility Focus To Label 2"
Clicked="Button2_Clicked"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />

<Button x:Name="theButton3"
Text="Set Accessibility Focus To Button 1"
Clicked="Button3_Clicked"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />

</StackLayout>

</ContentPage.Content>
</ContentPage>
15 changes: 10 additions & 5 deletions A11YTools/A11YTools/Views/SetFocus.xaml.cs
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
Expand All @@ -21,7 +17,16 @@ public SetFocus()

private void Button_Clicked(object sender, EventArgs e)
{
_a11yService.SetFocus(theLabel);
_a11yService.SetFocus(afcLabel);
}
private void Button2_Clicked(object sender, EventArgs e)
{
_a11yService.SetFocus(afcLabel2);
}

private void Button3_Clicked(object sender, EventArgs e)
{
_a11yService.SetFocus(theButton1);
}
}
}

0 comments on commit c0d8784

Please sign in to comment.