summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamantha Houts <samantha@teamredwall.com>2017-01-31 11:49:15 -0800
committerGitHub <noreply@github.com>2017-01-31 11:49:15 -0800
commitae59382c9046501edb37882ad1c065aacce60319 (patch)
tree3578ce8e0396a38aeb8323d4051f50a19a5340fb
parent23d228039acc504049f6a5153f5839d4c714930a (diff)
downloadxamarin-forms-ae59382c9046501edb37882ad1c065aacce60319.tar.gz
xamarin-forms-ae59382c9046501edb37882ad1c065aacce60319.tar.bz2
xamarin-forms-ae59382c9046501edb37882ad1c065aacce60319.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
-rw-r--r--Xamarin.Forms.Controls/ControlGalleryPages/AccessibilityGallery.cs145
-rw-r--r--Xamarin.Forms.Controls/CoreGallery.cs10
-rw-r--r--Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj713
-rw-r--r--Xamarin.Forms.Core.Windows.UITests/Xamarin.Forms.Core.Windows.UITests.csproj3
-rw-r--r--Xamarin.Forms.Core/Accessibility.cs14
-rw-r--r--Xamarin.Forms.Core/Xamarin.Forms.Core.csproj1
-rw-r--r--Xamarin.Forms.Platform.Android/AppCompat/FrameRenderer.cs9
-rw-r--r--Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs4
-rw-r--r--Xamarin.Forms.Platform.Android/IVisualElementRenderer.cs3
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/MasterDetailRenderer.cs4
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs4
-rw-r--r--Xamarin.Forms.Platform.Android/ViewRenderer.cs99
-rw-r--r--Xamarin.Forms.Platform.Android/VisualElementExtensions.cs12
-rw-r--r--Xamarin.Forms.Platform.Android/VisualElementRenderer.cs77
-rw-r--r--Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs5
-rw-r--r--Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs7
-rw-r--r--Xamarin.Forms.Platform.WinRT.Phone/TabbedPageRenderer.cs5
-rw-r--r--Xamarin.Forms.Platform.WinRT.Tablet/TabbedPageRenderer.cs5
-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
-rw-r--r--Xamarin.Forms.Platform.iOS/Renderers/ButtonRenderer.cs15
-rw-r--r--Xamarin.Forms.Platform.iOS/Renderers/LabelRenderer.cs17
-rw-r--r--Xamarin.Forms.Platform.iOS/ViewRenderer.cs57
-rw-r--r--Xamarin.Forms.Platform.iOS/VisualElementRenderer.cs55
-rw-r--r--docs/Xamarin.Forms.Core/Xamarin.Forms/Accessibility.xml91
30 files changed, 1215 insertions, 375 deletions
diff --git a/Xamarin.Forms.Controls/ControlGalleryPages/AccessibilityGallery.cs b/Xamarin.Forms.Controls/ControlGalleryPages/AccessibilityGallery.cs
new file mode 100644
index 00000000..e2354153
--- /dev/null
+++ b/Xamarin.Forms.Controls/ControlGalleryPages/AccessibilityGallery.cs
@@ -0,0 +1,145 @@
+
+namespace Xamarin.Forms.Controls
+{
+ public class AccessibilityGallery : ContentPage
+ {
+ public AccessibilityGallery()
+ {
+ // https://developer.xamarin.com/guides/android/advanced_topics/accessibility/
+ // https://developer.xamarin.com/guides/ios/advanced_topics/accessibility/
+ // https://msdn.microsoft.com/en-us/windows/uwp/accessibility/basic-accessibility-information
+
+ string screenReader = "";
+ string scrollFingers = "";
+ string explore = "";
+
+ switch (Device.RuntimePlatform)
+ {
+ case Device.iOS:
+ screenReader = "VoiceOver";
+ scrollFingers = "three fingers";
+ explore = "Use two fingers to swipe up or down the screen to read all of the elements on this page.";
+ break;
+ case Device.Android:
+ screenReader = "TalkBack";
+ scrollFingers = "two fingers";
+ explore = "Drag one finger across the screen to read each element on the page.";
+ break;
+ case Device.Windows:
+ case Device.WinPhone:
+ screenReader = "Narrator";
+ scrollFingers = "two fingers";
+ break;
+ default:
+ screenReader = "the native screen reader";
+ break;
+ }
+
+ var instructions = new Label { Text = $"Please enable {screenReader}. {explore} Use {scrollFingers} to scroll the view. Tap an element once to hear the description. Double tap anywhere on the screen to activate the selected element. Swipe left or right with one finger to switch to the previous or next element." };
+
+ const string EntryPlaceholder = "Your name";
+ const string EntryHint = "Type your name.";
+
+ var instructions2 = new Label { Text = $"The following Entry should read aloud \"{EntryPlaceholder}. {EntryHint}\", plus native instructions on how to use an entry element. Note that Android will NOT read the Hint if a Placeholder is provided." };
+ var entry = new Entry { Placeholder = EntryPlaceholder };
+ entry.SetAccessibilityHint(EntryHint);
+
+
+ var activityIndicator = new ActivityIndicator();
+ activityIndicator.SetAccessibilityName("Progress indicator");
+
+
+ const string ButtonText = "Update progress";
+ var instructions3 = new Label { Text = $"The following Button should read aloud \"{ButtonText}\", plus native instructions on how to use a button." };
+ var button = new Button { Text = ButtonText };
+ button.Clicked += (sender, e) =>
+ {
+ activityIndicator.IsRunning = !activityIndicator.IsRunning;
+ activityIndicator.SetAccessibilityHint(activityIndicator.IsRunning ? "Running." : "Not running");
+ };
+
+
+ const string ImageHint = "Tap to show an alert.";
+ var instructions4 = new Label { Text = $"The following Image should read aloud \"{ImageHint}\". You should be able to tap the image and hear an alert box." };
+ var image = new Image { Source = "photo.jpg" };
+ image.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => DisplayAlert("Success", "You tapped the image", "OK")) });
+ image.SetAccessibilityHint(ImageHint);
+ // images are ignored by default on iOS (at least, Forms images are);
+ // make accessible in order to enable the gesture and narration
+ image.SetIsInAccessibleTree(true);
+
+
+ var instructions5 = new Label { Text = $"The following Button should NOT be read aloud, nor should you be able to interact with it while {screenReader} is active." };
+ var button2 = new Button { Text = "I am not accessible" };
+ // setting this to false seems to have no effect on any platform
+ button2.SetIsInAccessibleTree(false);
+
+
+ var boxView = new BoxView { Color = Color.Purple };
+ boxView.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => DisplayAlert("Success", "You tapped the box", "OK")) });
+ boxView.SetAccessibilityName("Box");
+ boxView.SetAccessibilityHint("Shows a purple box.");
+ //boxView.SetIsInAccessibleTree(true);
+
+ var stack = new StackLayout
+ {
+ Children =
+ {
+ instructions,
+ instructions2,
+ entry,
+ instructions3,
+ button,
+ activityIndicator,
+ instructions4,
+ image,
+ instructions5,
+ button2,
+ boxView
+ }
+ };
+
+ var scrollView = new ScrollView { Content = stack };
+
+ // TODO: Test Pan/Pinch gestures
+ // TODO: Test CarouselView
+
+ Content = scrollView;
+ }
+
+ }
+
+
+ public static class AccessibilityExtensions
+ {
+ public static void SetAccessibilityName(this VisualElement element, string name)
+ {
+ element.SetValue(Accessibility.NameProperty, name);
+ }
+
+ public static string GetAccessibilityName(this VisualElement element)
+ {
+ return (string)element.GetValue(Accessibility.NameProperty);
+ }
+
+ public static void SetAccessibilityHint(this VisualElement element, string hint)
+ {
+ element.SetValue(Accessibility.HintProperty, hint);
+ }
+
+ public static string GetAccessibilityHint(this VisualElement element)
+ {
+ return (string)element.GetValue(Accessibility.HintProperty);
+ }
+
+ public static void SetIsInAccessibleTree(this VisualElement element, bool value)
+ {
+ element.SetValue(Accessibility.IsInAccessibleTreeProperty, value);
+ }
+
+ public static bool GetIsInAccessibleTree(this VisualElement element)
+ {
+ return (bool)element.GetValue(Accessibility.IsInAccessibleTreeProperty);
+ }
+ }
+}
diff --git a/Xamarin.Forms.Controls/CoreGallery.cs b/Xamarin.Forms.Controls/CoreGallery.cs
index 83d8ec6c..924d4129 100644
--- a/Xamarin.Forms.Controls/CoreGallery.cs
+++ b/Xamarin.Forms.Controls/CoreGallery.cs
@@ -212,6 +212,7 @@ namespace Xamarin.Forms.Controls
}
};
#endif
+ SetValue(Accessibility.NameProperty, "SwapRoot");
}
}
@@ -235,9 +236,16 @@ namespace Xamarin.Forms.Controls
public Func<Page> Realize { get; set; }
public string Title { get; set; }
+
+ public override string ToString()
+ {
+ // a11y: let Narrator read a friendly string instead of the default ToString()
+ return Title;
+ }
}
List<GalleryPageFactory> _pages = new List<GalleryPageFactory> {
+ new GalleryPageFactory(() => new AccessibilityGallery(), "Accessibility"),
new GalleryPageFactory(() => new PlatformSpecificsGallery(), "Platform Specifics"),
new GalleryPageFactory(() => new NativeBindingGalleryPage(), "Native Binding Controls Gallery"),
new GalleryPageFactory(() => new XamlNativeViews(), "Xaml Native Views Gallery"),
@@ -368,6 +376,8 @@ namespace Xamarin.Forms.Controls
SelectedItem = null;
};
+
+ SetValue(Accessibility.NameProperty, "Core Pages");
}
NavigationBehavior navigationBehavior;
diff --git a/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj b/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj
index fa6da678..717f31e0 100644
--- a/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj
+++ b/Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj
@@ -1,365 +1,366 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{CB9C96CE-125C-4A68-B6A1-C3FF1FBF93E1}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Xamarin.Forms.Controls</RootNamespace>
- <AssemblyName>Xamarin.Forms.Controls</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <RestorePackages>true</RestorePackages>
- <NuGetPackageImportStamp>
- </NuGetPackageImportStamp>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>TRACE;DEBUG;PERF;APP</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
- <NoWarn>0114;0108;0109;4014;0649;0169;0472;0414;0168;0219;0429</NoWarn>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE;APP</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
- <NoWarn>0114;0108;0109;4014;0649;0169;0472;0414;0168;0219;0429</NoWarn>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Turkey|AnyCPU'">
- <DebugSymbols>true</DebugSymbols>
- <OutputPath>bin\Turkey\</OutputPath>
- <DefineConstants>TRACE;DEBUG;PERF;APP</DefineConstants>
- <DebugType>full</DebugType>
- <PlatformTarget>AnyCPU</PlatformTarget>
- <ErrorReport>prompt</ErrorReport>
- <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
- <WarningLevel>4</WarningLevel>
- <Optimize>false</Optimize>
- <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
- <NoWarn>0114;0108;0109;4014;0649;0169;0472;0414;0168;0219;0429</NoWarn>
- </PropertyGroup>
- <ItemGroup>
- <!-- A reference to the entire .NET Framework is automatically included -->
- <ProjectReference Include="..\Xamarin.Forms.Core\Xamarin.Forms.Core.csproj">
- <Project>{57B8B73D-C3B5-4C42-869E-7B2F17D354AC}</Project>
- <Name>Xamarin.Forms.Core</Name>
- </ProjectReference>
- <ProjectReference Include="..\Xamarin.Forms.Build.Tasks\Xamarin.Forms.Build.Tasks.csproj">
- <Project>{96D89208-4EB9-4451-BE73-8A9DF3D9D7B7}</Project>
- <Name>Xamarin.Forms.Build.Tasks</Name>
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
- </ProjectReference>
- <ProjectReference Include="..\Xamarin.Forms.CustomAttributes\Xamarin.Forms.CustomAttributes.csproj">
- <Project>{4dcd0420-1168-4b77-86db-6196ee4bd491}</Project>
- <Name>Xamarin.Forms.CustomAttributes</Name>
- </ProjectReference>
- <ProjectReference Include="..\Xamarin.Forms.Maps\Xamarin.Forms.Maps.csproj">
- <Project>{7d13bac2-c6a4-416a-b07e-c169b199e52b}</Project>
- <Name>Xamarin.Forms.Maps</Name>
- </ProjectReference>
- <ProjectReference Include="..\Xamarin.Forms.Pages\Xamarin.Forms.Pages.csproj">
- <Project>{d6133dbd-6c60-4bd5-bea2-07e0a3927c31}</Project>
- <Name>Xamarin.Forms.Pages</Name>
- </ProjectReference>
- <ProjectReference Include="..\Xamarin.Forms.Xaml\Xamarin.Forms.Xaml.csproj">
- <Project>{9db2f292-8034-4e06-89ad-98bbda4306b9}</Project>
- <Name>Xamarin.Forms.Xaml</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="App.cs" />
- <Compile Include="AppLifeCycle.cs" />
- <Compile Include="Bugzilla44596SplashPage.cs" />
- <Compile Include="ControlGalleryPages\CellForceUpdateSizeGalleryPage.cs" />
- <Compile Include="ControlGalleryPages\LayoutAddPerformance.xaml.cs">
- <DependentUpon>LayoutAddPerformance.xaml</DependentUpon>
- </Compile>
- <Compile Include="ControlGalleryPages\ListScrollTo.cs" />
- <Compile Include="ControlGalleryPages\NavBarTitleTestPage.cs" />
- <Compile Include="ControlGalleryPages\NestedNativeControlGalleryPage.cs" />
- <Compile Include="ControlGalleryPages\PanGestureGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\KeyboardCoreGalleryPage.cs" />
- <Compile Include="GalleryPages\BackgroundImageGallery.cs" />
- <Compile Include="GalleryPages\ControlTemplatePage.cs" />
- <Compile Include="GalleryPages\ControlTemplateXamlPage.xaml.cs">
- <DependentUpon>ControlTemplateXamlPage.xaml</DependentUpon>
- </Compile>
- <Compile Include="GalleryPages\LayoutPerformanceGallery.cs" />
- <Compile Include="GalleryPages\NavigationPropertiesGallery.cs" />
- <Compile Include="ControlGalleryPages\ListViewSelectionColor.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\ApplicationAndroid.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\EntryPageiOS.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\MasterDetailPageiOS.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\MasterDetailPageWindows.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\NavigationPageiOS.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\NavigationPageWindows.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\TabbedPageAndroid.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\TabbedPageiOS.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\TabbedPageWindows.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\VisualElementiOS.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGalleries\WindowsPlatformSpecificsGalleryHelpers.cs" />
- <Compile Include="GalleryPages\PlatformSpecificsGallery.cs" />
- <Compile Include="LegacyRepro\Page1.xaml.cs">
- <DependentUpon>Page1.xaml</DependentUpon>
- </Compile>
- <Compile Include="MainPageLifeCycleTests.cs" />
- <Compile Include="NavReproApp.cs" />
- <Compile Include="RootPages\RootContentPage.cs" />
- <Compile Include="RootPages\SwapHierachyStackLayout.cs" />
- <Compile Include="GalleryPages\EditableList.cs" />
- <Compile Include="CoreGalleryPages\EditorCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\EntryCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\FrameCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\ImageCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\LabelCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\ListViewCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\OpenGLViewCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\PickerCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\ProgressBarCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\SearchBarCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\SliderCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\StepperCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\SwitchCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\TableViewCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\TimePickerCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\WebViewCoreGalleryPage.cs" />
- <Compile Include="LegacyRepro\SampleViewCell.xaml.cs">
- <DependentUpon>SampleViewCell.xaml</DependentUpon>
- </Compile>
- <Compile Include="SimpleApp.cs" />
- <Compile Include="ViewContainers\EventViewContainer.cs" />
- <Compile Include="ViewContainers\LayeredViewContainer.cs" />
- <Compile Include="ViewContainers\MultiBindingHack.cs" />
- <Compile Include="ViewContainers\StateViewContainer.cs" />
- <Compile Include="ViewContainers\ValueViewContainer.cs" />
- <Compile Include="ViewContainers\ViewContainer.cs" />
- <Compile Include="CoreGalleryPages\ActivityIndicatorCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\CoreBoxViewGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\ButtonCoreGalleryPage.cs" />
- <Compile Include="CoreGallery.cs" />
- <Compile Include="CoreGalleryPages\DatePickerCoreGalleryPage.cs" />
- <Compile Include="CoreGalleryPages\CoreGalleryPage.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="TestCases.cs" />
- <Compile Include="GalleryPages\GridGallery.cs" />
- <Compile Include="GalleryPages\PickerGallery.cs" />
- <Compile Include="GalleryPages\ImageLoadingGallery.cs" />
- <Compile Include="GalleryPages\CarouselPageGallery.cs" />
- <Compile Include="GalleryPages\StepperGallery.cs" />
- <Compile Include="GalleryPages\ScaleRotate.cs" />
- <Compile Include="GalleryPages\LineBreakModeGallery.cs" />
- <Compile Include="GalleryPages\ActionSheetGallery.cs" />
- <Compile Include="GalleryPages\XamlPage.xaml.cs">
- <DependentUpon>XamlPage.xaml</DependentUpon>
- </Compile>
- <Compile Include="RootPages\RootTabbedContentPage.cs" />
- <Compile Include="RootPages\RootTabbedNavigationContentPage.cs" />
- <Compile Include="RootPages\RootNavigationContentPage.cs" />
- <Compile Include="RootPages\RootNavigationTabbedContentPage.cs" />
- <Compile Include="RootPages\RootMDPNavigationContentPage.cs" />
- <Compile Include="RootPages\RootTabbedMDPNavigationContentPage.cs" />
- <Compile Include="RootPages\RootTabbedManyNavigationContentPage.cs" />
- <Compile Include="RootPages\RootNavigationManyTabbedPage.cs" />
- <Compile Include="ControlGalleryPages\BehaviorsAndTriggers.xaml.cs">
- <DependentUpon>BehaviorsAndTriggers.xaml</DependentUpon>
- </Compile>
- <Compile Include="GalleryPages\CellsGalleries\EntryCellListPage.cs" />
- <Compile Include="GalleryPages\CellsGalleries\EntryCellTablePage.cs" />
- <Compile Include="GalleryPages\CellsGalleries\ImageCellListPage.cs" />
- <Compile Include="GalleryPages\CellsGalleries\ImageCellTablePage.cs" />
- <Compile Include="GalleryPages\CellsGalleries\ProductViewCell.cs" />
- <Compile Include="GalleryPages\CellsGalleries\SwitchCellListPage.cs" />
- <Compile Include="GalleryPages\CellsGalleries\SwitchCellTablePage.cs" />
- <Compile Include="GalleryPages\CellsGalleries\TextCellListPage.cs" />
- <Compile Include="GalleryPages\CellsGalleries\TextCellTablePage.cs" />
- <Compile Include="GalleryPages\CellsGalleries\UnEvenViewCellGallery.cs" />
- <Compile Include="GalleryPages\CellsGalleries\ViewCellGallery.cs" />
- <Compile Include="GalleryPages\AbsoluteLayoutGallery.cs" />
- <Compile Include="GalleryPages\BoundContentPage.cs" />
- <Compile Include="GalleryPages\ButtonGallery.cs" />
- <Compile Include="GalleryPages\CellTypeList.cs" />
- <Compile Include="GalleryPages\ClipToBoundsGallery.cs" />
- <Compile Include="GalleryPages\DisposeGallery.cs" />
- <Compile Include="GalleryPages\EditorGallery.cs" />
- <Compile Include="GalleryPages\EntryGallery.cs" />
- <Compile Include="GalleryPages\FrameGallery.cs" />
- <Compile Include="GalleryPages\GroupedListActionsGallery.cs" />
- <Compile Include="GalleryPages\GroupedListContactsGallery.cs" />
- <Compile Include="GalleryPages\ImageGallery.cs" />
- <Compile Include="GalleryPages\InputIntentGallery.cs" />
- <Compile Include="GalleryPages\LabelGallery.cs" />
- <Compile Include="GalleryPages\LayoutOptionsGallery.cs" />
- <Compile Include="GalleryPages\ListPage.cs" />
- <Compile Include="GalleryPages\ListViewDemoPage.cs" />
- <Compile Include="GalleryPages\MapGallery.cs" />
- <Compile Include="GalleryPages\MinimumSizeGallery.cs" />
- <Compile Include="GalleryPages\MultiGallery.cs" />
- <Compile Include="GalleryPages\NavigationBarGallery.cs" />
- <Compile Include="GalleryPages\NavigationMenuGallery.cs" />
- <Compile Include="GalleryPages\OpenGLGallery.cs" />
- <Compile Include="GalleryPages\ProgressBarGallery.cs" />
- <Compile Include="GalleryPages\RelativeLayoutGallery.cs" />
- <Compile Include="GalleryPages\ScrollGallery.cs" />
- <Compile Include="GalleryPages\SearchBarGallery.cs" />
- <Compile Include="GalleryPages\SettingsPage.cs" />
- <Compile Include="GalleryPages\SliderGallery.cs" />
- <Compile Include="GalleryPages\StackLayoutGallery.cs" />
- <Compile Include="GalleryPages\SwitchGallery.cs" />
- <Compile Include="GalleryPages\TableViewGallery.cs" />
- <Compile Include="GalleryPages\TemplatedCarouselGallery.cs" />
- <Compile Include="GalleryPages\TemplatedTabbedGallery.cs" />
- <Compile Include="GalleryPages\UnevenListGallery.cs" />
- <Compile Include="GalleryPages\WebViewGallery.cs" />
- <Compile Include="GalleryPages\StyleGallery.cs" />
- <Compile Include="GalleryPages\StyleXamlGallery.xaml.cs">
- <DependentUpon>StyleXamlGallery.xaml</DependentUpon>
- </Compile>
- <Compile Include="GalleryPages\MasterDetailPageTabletPage.cs" />
- <Compile Include="Helpers\ITestCloudService.cs" />
- <Compile Include="ControlGalleryPages\ToolbarItems.cs" />
- <Compile Include="GalleryPages\AlertGallery.cs" />
- <Compile Include="RootPages\RootMDPNavigationTabbedContentPage.cs" />
- <Compile Include="Controls\Issue3076Button.cs" />
- <Compile Include="ControlGalleryPages\ListRefresh.cs" />
- <Compile Include="ControlGalleryPages\PinchGestureTestPage.cs" />
- <Compile Include="ControlGalleryPages\AppearingGalleryPage.cs" />
- <Compile Include="ControlGalleryPages\AutomationIDGallery.cs" />
- <Compile Include="GalleryPages\AppLinkPageGallery.cs" />
- <Compile Include="ControlGalleryPages\NativeBindingGalleryPage.cs" />
- <Compile Include="GalleryPages\XamlNativeViews.xaml.cs">
- <DependentUpon>XamlNativeViews.xaml</DependentUpon>
- </Compile>
- <Compile Include="HanselForms\BaseView.cs" />
- <Compile Include="HanselForms\HBaseViewModel.cs" />
- <Compile Include="HanselForms\RootPage.cs" />
- <Compile Include="HanselForms\WebsiteView.cs" />
- <Compile Include="HanselForms\BlogPage.xaml.cs">
- <DependentUpon>BlogPage.xaml</DependentUpon>
- </Compile>
- <Compile Include="HanselForms\MyAbout.xaml.cs">
- <DependentUpon>MyAbout.xaml</DependentUpon>
- </Compile>
- <Compile Include="HanselForms\TwitterPage.xaml.cs">
- <DependentUpon>TwitterPage.xaml</DependentUpon>
- </Compile>
- <Compile Include="GalleryPages\MacTwitterDemo.xaml.cs">
- <DependentUpon>MacTwitterDemo.xaml</DependentUpon>
- </Compile>
- </ItemGroup>
- <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
- <Import Project="..\.nuspec\Xamarin.Forms.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{CB9C96CE-125C-4A68-B6A1-C3FF1FBF93E1}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Xamarin.Forms.Controls</RootNamespace>
+ <AssemblyName>Xamarin.Forms.Controls</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;PERF;APP</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ <NoWarn>0114;0108;0109;4014;0649;0169;0472;0414;0168;0219;0429</NoWarn>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE;APP</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ <NoWarn>0114;0108;0109;4014;0649;0169;0472;0414;0168;0219;0429</NoWarn>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Turkey|AnyCPU'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Turkey\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;PERF;APP</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+ <WarningLevel>4</WarningLevel>
+ <Optimize>false</Optimize>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ <NoWarn>0114;0108;0109;4014;0649;0169;0472;0414;0168;0219;0429</NoWarn>
+ </PropertyGroup>
+ <ItemGroup>
+ <!-- A reference to the entire .NET Framework is automatically included -->
+ <ProjectReference Include="..\Xamarin.Forms.Core\Xamarin.Forms.Core.csproj">
+ <Project>{57B8B73D-C3B5-4C42-869E-7B2F17D354AC}</Project>
+ <Name>Xamarin.Forms.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Xamarin.Forms.Build.Tasks\Xamarin.Forms.Build.Tasks.csproj">
+ <Project>{96D89208-4EB9-4451-BE73-8A9DF3D9D7B7}</Project>
+ <Name>Xamarin.Forms.Build.Tasks</Name>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ <ProjectReference Include="..\Xamarin.Forms.CustomAttributes\Xamarin.Forms.CustomAttributes.csproj">
+ <Project>{4dcd0420-1168-4b77-86db-6196ee4bd491}</Project>
+ <Name>Xamarin.Forms.CustomAttributes</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Xamarin.Forms.Maps\Xamarin.Forms.Maps.csproj">
+ <Project>{7d13bac2-c6a4-416a-b07e-c169b199e52b}</Project>
+ <Name>Xamarin.Forms.Maps</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Xamarin.Forms.Pages\Xamarin.Forms.Pages.csproj">
+ <Project>{d6133dbd-6c60-4bd5-bea2-07e0a3927c31}</Project>
+ <Name>Xamarin.Forms.Pages</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Xamarin.Forms.Xaml\Xamarin.Forms.Xaml.csproj">
+ <Project>{9db2f292-8034-4e06-89ad-98bbda4306b9}</Project>
+ <Name>Xamarin.Forms.Xaml</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="App.cs" />
+ <Compile Include="AppLifeCycle.cs" />
+ <Compile Include="Bugzilla44596SplashPage.cs" />
+ <Compile Include="ControlGalleryPages\AccessibilityGallery.cs" />
+ <Compile Include="ControlGalleryPages\CellForceUpdateSizeGalleryPage.cs" />
+ <Compile Include="ControlGalleryPages\LayoutAddPerformance.xaml.cs">
+ <DependentUpon>LayoutAddPerformance.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="ControlGalleryPages\ListScrollTo.cs" />
+ <Compile Include="ControlGalleryPages\NavBarTitleTestPage.cs" />
+ <Compile Include="ControlGalleryPages\NestedNativeControlGalleryPage.cs" />
+ <Compile Include="ControlGalleryPages\PanGestureGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\KeyboardCoreGalleryPage.cs" />
+ <Compile Include="GalleryPages\BackgroundImageGallery.cs" />
+ <Compile Include="GalleryPages\ControlTemplatePage.cs" />
+ <Compile Include="GalleryPages\ControlTemplateXamlPage.xaml.cs">
+ <DependentUpon>ControlTemplateXamlPage.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="GalleryPages\LayoutPerformanceGallery.cs" />
+ <Compile Include="GalleryPages\NavigationPropertiesGallery.cs" />
+ <Compile Include="ControlGalleryPages\ListViewSelectionColor.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\ApplicationAndroid.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\EntryPageiOS.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\MasterDetailPageiOS.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\MasterDetailPageWindows.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\NavigationPageiOS.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\NavigationPageWindows.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\TabbedPageAndroid.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\TabbedPageiOS.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\TabbedPageWindows.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\VisualElementiOS.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGalleries\WindowsPlatformSpecificsGalleryHelpers.cs" />
+ <Compile Include="GalleryPages\PlatformSpecificsGallery.cs" />
+ <Compile Include="LegacyRepro\Page1.xaml.cs">
+ <DependentUpon>Page1.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="MainPageLifeCycleTests.cs" />
+ <Compile Include="NavReproApp.cs" />
+ <Compile Include="RootPages\RootContentPage.cs" />
+ <Compile Include="RootPages\SwapHierachyStackLayout.cs" />
+ <Compile Include="GalleryPages\EditableList.cs" />
+ <Compile Include="CoreGalleryPages\EditorCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\EntryCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\FrameCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\ImageCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\LabelCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\ListViewCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\OpenGLViewCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\PickerCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\ProgressBarCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\SearchBarCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\SliderCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\StepperCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\SwitchCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\TableViewCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\TimePickerCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\WebViewCoreGalleryPage.cs" />
+ <Compile Include="LegacyRepro\SampleViewCell.xaml.cs">
+ <DependentUpon>SampleViewCell.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="SimpleApp.cs" />
+ <Compile Include="ViewContainers\EventViewContainer.cs" />
+ <Compile Include="ViewContainers\LayeredViewContainer.cs" />
+ <Compile Include="ViewContainers\MultiBindingHack.cs" />
+ <Compile Include="ViewContainers\StateViewContainer.cs" />
+ <Compile Include="ViewContainers\ValueViewContainer.cs" />
+ <Compile Include="ViewContainers\ViewContainer.cs" />
+ <Compile Include="CoreGalleryPages\ActivityIndicatorCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\CoreBoxViewGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\ButtonCoreGalleryPage.cs" />
+ <Compile Include="CoreGallery.cs" />
+ <Compile Include="CoreGalleryPages\DatePickerCoreGalleryPage.cs" />
+ <Compile Include="CoreGalleryPages\CoreGalleryPage.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="TestCases.cs" />
+ <Compile Include="GalleryPages\GridGallery.cs" />
+ <Compile Include="GalleryPages\PickerGallery.cs" />
+ <Compile Include="GalleryPages\ImageLoadingGallery.cs" />
+ <Compile Include="GalleryPages\CarouselPageGallery.cs" />
+ <Compile Include="GalleryPages\StepperGallery.cs" />
+ <Compile Include="GalleryPages\ScaleRotate.cs" />
+ <Compile Include="GalleryPages\LineBreakModeGallery.cs" />
+ <Compile Include="GalleryPages\ActionSheetGallery.cs" />
+ <Compile Include="GalleryPages\XamlPage.xaml.cs">
+ <DependentUpon>XamlPage.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="RootPages\RootTabbedContentPage.cs" />
+ <Compile Include="RootPages\RootTabbedNavigationContentPage.cs" />
+ <Compile Include="RootPages\RootNavigationContentPage.cs" />
+ <Compile Include="RootPages\RootNavigationTabbedContentPage.cs" />
+ <Compile Include="RootPages\RootMDPNavigationContentPage.cs" />
+ <Compile Include="RootPages\RootTabbedMDPNavigationContentPage.cs" />
+ <Compile Include="RootPages\RootTabbedManyNavigationContentPage.cs" />
+ <Compile Include="RootPages\RootNavigationManyTabbedPage.cs" />
+ <Compile Include="ControlGalleryPages\BehaviorsAndTriggers.xaml.cs">
+ <DependentUpon>BehaviorsAndTriggers.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="GalleryPages\CellsGalleries\EntryCellListPage.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\EntryCellTablePage.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\ImageCellListPage.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\ImageCellTablePage.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\ProductViewCell.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\SwitchCellListPage.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\SwitchCellTablePage.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\TextCellListPage.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\TextCellTablePage.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\UnEvenViewCellGallery.cs" />
+ <Compile Include="GalleryPages\CellsGalleries\ViewCellGallery.cs" />
+ <Compile Include="GalleryPages\AbsoluteLayoutGallery.cs" />
+ <Compile Include="GalleryPages\BoundContentPage.cs" />
+ <Compile Include="GalleryPages\ButtonGallery.cs" />
+ <Compile Include="GalleryPages\CellTypeList.cs" />
+ <Compile Include="GalleryPages\ClipToBoundsGallery.cs" />
+ <Compile Include="GalleryPages\DisposeGallery.cs" />
+ <Compile Include="GalleryPages\EditorGallery.cs" />
+ <Compile Include="GalleryPages\EntryGallery.cs" />
+ <Compile Include="GalleryPages\FrameGallery.cs" />
+ <Compile Include="GalleryPages\GroupedListActionsGallery.cs" />
+ <Compile Include="GalleryPages\GroupedListContactsGallery.cs" />
+ <Compile Include="GalleryPages\ImageGallery.cs" />
+ <Compile Include="GalleryPages\InputIntentGallery.cs" />
+ <Compile Include="GalleryPages\LabelGallery.cs" />
+ <Compile Include="GalleryPages\LayoutOptionsGallery.cs" />
+ <Compile Include="GalleryPages\ListPage.cs" />
+ <Compile Include="GalleryPages\ListViewDemoPage.cs" />
+ <Compile Include="GalleryPages\MapGallery.cs" />
+ <Compile Include="GalleryPages\MinimumSizeGallery.cs" />
+ <Compile Include="GalleryPages\MultiGallery.cs" />
+ <Compile Include="GalleryPages\NavigationBarGallery.cs" />
+ <Compile Include="GalleryPages\NavigationMenuGallery.cs" />
+ <Compile Include="GalleryPages\OpenGLGallery.cs" />
+ <Compile Include="GalleryPages\ProgressBarGallery.cs" />
+ <Compile Include="GalleryPages\RelativeLayoutGallery.cs" />
+ <Compile Include="GalleryPages\ScrollGallery.cs" />
+ <Compile Include="GalleryPages\SearchBarGallery.cs" />
+ <Compile Include="GalleryPages\SettingsPage.cs" />
+ <Compile Include="GalleryPages\SliderGallery.cs" />
+ <Compile Include="GalleryPages\StackLayoutGallery.cs" />
+ <Compile Include="GalleryPages\SwitchGallery.cs" />
+ <Compile Include="GalleryPages\TableViewGallery.cs" />
+ <Compile Include="GalleryPages\TemplatedCarouselGallery.cs" />
+ <Compile Include="GalleryPages\TemplatedTabbedGallery.cs" />
+ <Compile Include="GalleryPages\UnevenListGallery.cs" />
+ <Compile Include="GalleryPages\WebViewGallery.cs" />
+ <Compile Include="GalleryPages\StyleGallery.cs" />
+ <Compile Include="GalleryPages\StyleXamlGallery.xaml.cs">
+ <DependentUpon>StyleXamlGallery.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="GalleryPages\MasterDetailPageTabletPage.cs" />
+ <Compile Include="Helpers\ITestCloudService.cs" />
+ <Compile Include="ControlGalleryPages\ToolbarItems.cs" />
+ <Compile Include="GalleryPages\AlertGallery.cs" />
+ <Compile Include="RootPages\RootMDPNavigationTabbedContentPage.cs" />
+ <Compile Include="Controls\Issue3076Button.cs" />
+ <Compile Include="ControlGalleryPages\ListRefresh.cs" />
+ <Compile Include="ControlGalleryPages\PinchGestureTestPage.cs" />
+ <Compile Include="ControlGalleryPages\AppearingGalleryPage.cs" />
+ <Compile Include="ControlGalleryPages\AutomationIDGallery.cs" />
+ <Compile Include="GalleryPages\AppLinkPageGallery.cs" />
+ <Compile Include="ControlGalleryPages\NativeBindingGalleryPage.cs" />
+ <Compile Include="GalleryPages\XamlNativeViews.xaml.cs">
+ <DependentUpon>XamlNativeViews.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="HanselForms\BaseView.cs" />
+ <Compile Include="HanselForms\HBaseViewModel.cs" />
+ <Compile Include="HanselForms\RootPage.cs" />
+ <Compile Include="HanselForms\WebsiteView.cs" />
+ <Compile Include="HanselForms\BlogPage.xaml.cs">
+ <DependentUpon>BlogPage.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="HanselForms\MyAbout.xaml.cs">
+ <DependentUpon>MyAbout.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="HanselForms\TwitterPage.xaml.cs">
+ <DependentUpon>TwitterPage.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="GalleryPages\MacTwitterDemo.xaml.cs">
+ <DependentUpon>MacTwitterDemo.xaml</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+ <Import Project="..\.nuspec\Xamarin.Forms.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
- <ItemGroup>
- <EmbeddedResource Include="GalleryPages\crimson.jpg" />
- <EmbeddedResource Include="GalleryPages\XamlPage.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
- <EmbeddedResource Include="ControlGalleryPages\BehaviorsAndTriggers.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
- <EmbeddedResource Include="GalleryPages\StyleXamlGallery.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
- <EmbeddedResource Include="GalleryPages\XamlNativeViews.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
- <EmbeddedResource Include="GalleryPages\MacTwitterDemo.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
- <EmbeddedResource Include="HanselForms\MyAbout.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
- <EmbeddedResource Include="HanselForms\BlogPage.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
- <EmbeddedResource Include="HanselForms\TwitterPage.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
- </ItemGroup>
- <Import Project="..\Xamarin.Forms.Controls.Issues\Xamarin.Forms.Controls.Issues.Shared\Xamarin.Forms.Controls.Issues.Shared.projitems" Label="Shared" />
- <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
- <Import Project="..\packages\Xamarin.Insights.1.11.1\build\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.targets" Condition="Exists('..\packages\Xamarin.Insights.1.11.1\build\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.targets')" />
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
- </Target>
- <ItemGroup>
- <EmbeddedResource Include="ControlGalleryPages\LayoutAddPerformance.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="GalleryPages\ControlTemplateXamlPage.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- </ItemGroup>
- <ItemGroup>
- <None Include="app.config" />
- <EmbeddedResource Include="controlgallery.config" />
- <None Include="packages.config" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="LegacyRepro\Page1.xaml">
- <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- <EmbeddedResource Include="LegacyRepro\SampleViewCell.xaml">
- <Generator>MSBuild:UpdateDeisgnTimeXaml</Generator>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- </ItemGroup>
- <ItemGroup>
- <Reference Include="PCLStorage, Version=1.0.2.0, Culture=neutral, PublicKeyToken=286fe515a2c35b64, processorArchitecture=MSIL">
- <HintPath>..\packages\PCLStorage.1.0.2\lib\portable-net45+wp8+wpa81+win8+monoandroid+monotouch+Xamarin.iOS+Xamarin.Mac\PCLStorage.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="PCLStorage.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=286fe515a2c35b64, processorArchitecture=MSIL">
- <HintPath>..\packages\PCLStorage.1.0.2\lib\portable-net45+wp8+wpa81+win8+monoandroid+monotouch+Xamarin.iOS+Xamarin.Mac\PCLStorage.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Xamarin.Insights">
- <HintPath>..\packages\Xamarin.Insights.1.12.3\lib\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.dll</HintPath>
- </Reference>
- <Reference Include="System.Net.Http">
- <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.dll</HintPath>
- </Reference>
- <Reference Include="System.Net.Http.Extensions">
- <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Extensions.dll</HintPath>
- </Reference>
- <Reference Include="System.Net.Http.Primitives">
- <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Primitives.dll</HintPath>
- </Reference>
- </ItemGroup>
- <Target Name="BeforeBuild">
- <CreateItem Include="blank.config">
- <Output TaskParameter="Include" ItemName="ConfigFile" />
- </CreateItem>
- <Copy SourceFiles="@(ConfigFile)" DestinationFiles="controlgallery.config" Condition="!Exists('controlgallery.config')" />
- </Target>
- <Import Project="..\packages\Xamarin.Insights.1.12.3\build\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.targets" Condition="Exists('..\packages\Xamarin.Insights.1.12.3\build\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.targets')" />
+ <ItemGroup>
+ <EmbeddedResource Include="GalleryPages\crimson.jpg" />
+ <EmbeddedResource Include="GalleryPages\XamlPage.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ <EmbeddedResource Include="ControlGalleryPages\BehaviorsAndTriggers.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ <EmbeddedResource Include="GalleryPages\StyleXamlGallery.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ <EmbeddedResource Include="GalleryPages\XamlNativeViews.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ <EmbeddedResource Include="GalleryPages\MacTwitterDemo.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ <EmbeddedResource Include="HanselForms\MyAbout.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ <EmbeddedResource Include="HanselForms\BlogPage.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ <EmbeddedResource Include="HanselForms\TwitterPage.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ </ItemGroup>
+ <Import Project="..\Xamarin.Forms.Controls.Issues\Xamarin.Forms.Controls.Issues.Shared\Xamarin.Forms.Controls.Issues.Shared.projitems" Label="Shared" />
+ <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
+ <Import Project="..\packages\Xamarin.Insights.1.11.1\build\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.targets" Condition="Exists('..\packages\Xamarin.Insights.1.11.1\build\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
+ </Target>
+ <ItemGroup>
+ <EmbeddedResource Include="ControlGalleryPages\LayoutAddPerformance.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="GalleryPages\ControlTemplateXamlPage.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ <EmbeddedResource Include="controlgallery.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="LegacyRepro\Page1.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <EmbeddedResource Include="LegacyRepro\SampleViewCell.xaml">
+ <Generator>MSBuild:UpdateDeisgnTimeXaml</Generator>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <Reference Include="PCLStorage, Version=1.0.2.0, Culture=neutral, PublicKeyToken=286fe515a2c35b64, processorArchitecture=MSIL">
+ <HintPath>..\packages\PCLStorage.1.0.2\lib\portable-net45+wp8+wpa81+win8+monoandroid+monotouch+Xamarin.iOS+Xamarin.Mac\PCLStorage.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="PCLStorage.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=286fe515a2c35b64, processorArchitecture=MSIL">
+ <HintPath>..\packages\PCLStorage.1.0.2\lib\portable-net45+wp8+wpa81+win8+monoandroid+monotouch+Xamarin.iOS+Xamarin.Mac\PCLStorage.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Xamarin.Insights">
+ <HintPath>..\packages\Xamarin.Insights.1.12.3\lib\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http">
+ <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http.Extensions">
+ <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Extensions.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http.Primitives">
+ <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Primitives.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <Target Name="BeforeBuild">
+ <CreateItem Include="blank.config">
+ <Output TaskParameter="Include" ItemName="ConfigFile" />
+ </CreateItem>
+ <Copy SourceFiles="@(ConfigFile)" DestinationFiles="controlgallery.config" Condition="!Exists('controlgallery.config')" />
+ </Target>
+ <Import Project="..\packages\Xamarin.Insights.1.12.3\build\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.targets" Condition="Exists('..\packages\Xamarin.Insights.1.12.3\build\portable-win+net45+wp80+windows8+wpa+MonoAndroid10+MonoTouch10\Xamarin.Insights.targets')" />
</Project> \ No newline at end of file
diff --git a/Xamarin.Forms.Core.Windows.UITests/Xamarin.Forms.Core.Windows.UITests.csproj b/Xamarin.Forms.Core.Windows.UITests/Xamarin.Forms.Core.Windows.UITests.csproj
index 0758b8bd..f297b073 100644
--- a/Xamarin.Forms.Core.Windows.UITests/Xamarin.Forms.Core.Windows.UITests.csproj
+++ b/Xamarin.Forms.Core.Windows.UITests/Xamarin.Forms.Core.Windows.UITests.csproj
@@ -209,6 +209,9 @@
<Name>Xamarin.Forms.Platform</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
<Import Project="..\Xamarin.Forms.Controls.Issues\Xamarin.Forms.Controls.Issues.Shared\Xamarin.Forms.Controls.Issues.Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/Xamarin.Forms.Core/Accessibility.cs b/Xamarin.Forms.Core/Accessibility.cs
new file mode 100644
index 00000000..e866d318
--- /dev/null
+++ b/Xamarin.Forms.Core/Accessibility.cs
@@ -0,0 +1,14 @@
+
+namespace Xamarin.Forms
+{
+ public class Accessibility
+ {
+ public static readonly BindableProperty HintProperty = BindableProperty.Create("Hint", typeof(string), typeof(Element), default(string));
+
+ public static readonly BindableProperty IsInAccessibleTreeProperty = BindableProperty.Create("IsInAccessibleTree", typeof(bool?), typeof(Element), null);
+
+ public static readonly BindableProperty LabeledByProperty = BindableProperty.Create("LabeledBy", typeof(VisualElement), typeof(Element), default(VisualElement));
+
+ public static readonly BindableProperty NameProperty = BindableProperty.Create("Name", typeof(string), typeof(Element), default(string));
+ }
+}
diff --git a/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj b/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj
index 6b978ac9..f1b7f6f3 100644
--- a/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj
+++ b/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj
@@ -50,6 +50,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="AbsoluteLayoutFlags.cs" />
+ <Compile Include="Accessibility.cs" />
<Compile Include="ActionSheetArguments.cs" />
<Compile Include="AlertArguments.cs" />
<Compile Include="AnimatableKey.cs" />
diff --git a/Xamarin.Forms.Platform.Android/AppCompat/FrameRenderer.cs b/Xamarin.Forms.Platform.Android/AppCompat/FrameRenderer.cs
index 1092f767..6954654b 100644
--- a/Xamarin.Forms.Platform.Android/AppCompat/FrameRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/AppCompat/FrameRenderer.cs
@@ -21,6 +21,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
float _defaultElevation = -1f;
float _defaultCornerRadius = -1f;
+ int? _defaultLabelFor;
bool _clickable;
bool _disposed;
@@ -106,6 +107,14 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
ContentDescription = Element.AutomationId;
}
+ void IVisualElementRenderer.SetLabelFor(int? id)
+ {
+ if (_defaultLabelFor == null)
+ _defaultLabelFor = LabelFor;
+
+ LabelFor = (int)(id ?? _defaultLabelFor);
+ }
+
VisualElementTracker IVisualElementRenderer.Tracker => _visualElementTracker;
void IVisualElementRenderer.UpdateLayout()
diff --git a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs
index 757a98b4..85ab6b73 100644
--- a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs
@@ -165,6 +165,10 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
_tracker = new VisualElementTracker(this);
}
+ void IVisualElementRenderer.SetLabelFor(int? id)
+ {
+ }
+
VisualElementTracker IVisualElementRenderer.Tracker => _tracker;
void IVisualElementRenderer.UpdateLayout()
diff --git a/Xamarin.Forms.Platform.Android/IVisualElementRenderer.cs b/Xamarin.Forms.Platform.Android/IVisualElementRenderer.cs
index 99393516..da565ce2 100644
--- a/Xamarin.Forms.Platform.Android/IVisualElementRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/IVisualElementRenderer.cs
@@ -17,6 +17,9 @@ namespace Xamarin.Forms.Platform.Android
SizeRequest GetDesiredSize(int widthConstraint, int heightConstraint);
void SetElement(VisualElement element);
+
+ void SetLabelFor(int? id);
+
void UpdateLayout();
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.Android/Renderers/MasterDetailRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/MasterDetailRenderer.cs
index ec9c620e..d18781a7 100644
--- a/Xamarin.Forms.Platform.Android/Renderers/MasterDetailRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/Renderers/MasterDetailRenderer.cs
@@ -287,6 +287,10 @@ namespace Xamarin.Forms.Platform.Android
SetDrawerLockMode(_page.IsGestureEnabled ? LockModeUnlocked : LockModeLockedClosed);
}
+ void IVisualElementRenderer.SetLabelFor(int? id)
+ {
+ }
+
void SetLockMode(int lockMode)
{
if (_currentLockMode != lockMode)
diff --git a/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs
index 6db51c23..a2e3ddb3 100644
--- a/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/Renderers/ScrollViewRenderer.cs
@@ -328,6 +328,10 @@ namespace Xamarin.Forms.Platform.Android
}
}
+ void IVisualElementRenderer.SetLabelFor(int? id)
+ {
+ }
+
void UpdateBackgroundColor()
{
SetBackgroundColor(Element.BackgroundColor.ToAndroid(Color.Transparent));
diff --git a/Xamarin.Forms.Platform.Android/ViewRenderer.cs b/Xamarin.Forms.Platform.Android/ViewRenderer.cs
index c4bd3fa0..31a9c282 100644
--- a/Xamarin.Forms.Platform.Android/ViewRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/ViewRenderer.cs
@@ -19,6 +19,9 @@ namespace Xamarin.Forms.Platform.Android
}
ViewGroup _container;
+ string _defaultContentDescription;
+ bool? _defaultFocusable;
+ string _defaultHint;
bool _disposed;
EventHandler<VisualElement.FocusRequestArgs> _focusChangeHandler;
@@ -66,7 +69,7 @@ namespace Xamarin.Forms.Platform.Android
{
if (Control == null)
return (base.GetDesiredSize(widthConstraint, heightConstraint));
-
+
AView view = _container == this ? (AView)Control : _container;
view.Measure(widthConstraint, heightConstraint);
@@ -124,6 +127,8 @@ namespace Xamarin.Forms.Platform.Android
if (e.PropertyName == VisualElement.IsEnabledProperty.PropertyName)
UpdateIsEnabled();
+ else if (e.PropertyName == Accessibility.LabeledByProperty.PropertyName)
+ SetLabeledBy();
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
@@ -155,6 +160,79 @@ namespace Xamarin.Forms.Platform.Android
}
}
+ protected override void SetContentDescription()
+ {
+ if (Control == null)
+ {
+ base.SetContentDescription();
+ return;
+ }
+
+ if (Element == null)
+ return;
+
+ if (SetHint())
+ return;
+
+ if (_defaultContentDescription == null)
+ _defaultContentDescription = Control.ContentDescription;
+
+ var elemValue = string.Join(" ", (string)Element.GetValue(Accessibility.NameProperty), (string)Element.GetValue(Accessibility.HintProperty));
+
+ if (!string.IsNullOrWhiteSpace(elemValue))
+ Control.ContentDescription = elemValue;
+ else
+ Control.ContentDescription = _defaultContentDescription;
+ }
+
+ protected override void SetFocusable()
+ {
+ if (Control == null)
+ {
+ base.SetFocusable();
+ return;
+ }
+
+ if (Element == null)
+ return;
+
+ if (!_defaultFocusable.HasValue)
+ _defaultFocusable = Control.Focusable;
+
+ Control.Focusable = (bool)((bool?)Element.GetValue(Accessibility.IsInAccessibleTreeProperty) ?? _defaultFocusable);
+ }
+
+ protected override bool SetHint()
+ {
+ if (Control == null)
+ {
+ return base.SetHint();
+ }
+
+ if (Element == null)
+ return false;
+
+ var textView = Control as global::Android.Widget.TextView;
+ if (textView == null)
+ return false;
+
+ // Let the specified Title/Placeholder take precedence, but don't set the ContentDescription (won't work anyway)
+ if (((Element as Picker)?.Title ?? (Element as Entry)?.Placeholder ?? (Element as EntryCell)?.Placeholder) != null)
+ return true;
+
+ if (_defaultHint == null)
+ _defaultHint = textView.Hint;
+
+ var elemValue = string.Join(". ", (string)Element.GetValue(Accessibility.NameProperty), (string)Element.GetValue(Accessibility.HintProperty));
+
+ if (!string.IsNullOrWhiteSpace(elemValue))
+ textView.Hint = elemValue;
+ else
+ textView.Hint = _defaultHint;
+
+ return true;
+ }
+
protected void SetNativeControl(TNativeView control)
{
SetNativeControl(control, this);
@@ -219,6 +297,25 @@ namespace Xamarin.Forms.Platform.Android
Control.OnFocusChangeListener = this;
UpdateIsEnabled();
+ SetLabeledBy();
+ }
+
+ void SetLabeledBy()
+ {
+ if (Element == null || Control == null)
+ return;
+
+ var elemValue = (VisualElement)Element.GetValue(Accessibility.LabeledByProperty);
+
+ if (elemValue != null)
+ {
+ var id = Control.Id;
+ if (id == -1)
+ id = Control.Id = FormsAppCompatActivity.GetUniqueId();
+
+ var renderer = elemValue?.GetRenderer();
+ renderer?.SetLabelFor(id);
+ }
}
void UpdateIsEnabled()
diff --git a/Xamarin.Forms.Platform.Android/VisualElementExtensions.cs b/Xamarin.Forms.Platform.Android/VisualElementExtensions.cs
index 13f2fffa..800a967e 100644
--- a/Xamarin.Forms.Platform.Android/VisualElementExtensions.cs
+++ b/Xamarin.Forms.Platform.Android/VisualElementExtensions.cs
@@ -1,7 +1,19 @@
+using System;
+
namespace Xamarin.Forms.Platform.Android
{
public static class VisualElementExtensions
{
+ public static IVisualElementRenderer GetRenderer(this VisualElement self)
+ {
+ if (self == null)
+ throw new ArgumentNullException("self");
+
+ IVisualElementRenderer renderer = Platform.GetRenderer(self);
+
+ return renderer;
+ }
+
public static bool ShouldBeMadeClickable(this View view)
{
var shouldBeClickable = false;
diff --git a/Xamarin.Forms.Platform.Android/VisualElementRenderer.cs b/Xamarin.Forms.Platform.Android/VisualElementRenderer.cs
index 19b05e2e..46bab02e 100644
--- a/Xamarin.Forms.Platform.Android/VisualElementRenderer.cs
+++ b/Xamarin.Forms.Platform.Android/VisualElementRenderer.cs
@@ -23,6 +23,10 @@ namespace Xamarin.Forms.Platform.Android
VisualElementRendererFlags _flags = VisualElementRendererFlags.AutoPackage | VisualElementRendererFlags.AutoTrack;
+ string _defaultContentDescription;
+ bool? _defaultFocusable;
+ string _defaultHint;
+ int? _defaultLabelFor;
InnerGestureListener _gestureListener;
VisualElementPackager _packager;
PropertyChangedEventHandler _propertyChangeHandler;
@@ -209,6 +213,9 @@ namespace Xamarin.Forms.Platform.Android
if (element != null && !string.IsNullOrEmpty(element.AutomationId))
SetAutomationId(element.AutomationId);
+ SetContentDescription();
+ SetFocusable();
+
Performance.Stop();
}
@@ -302,6 +309,12 @@ namespace Xamarin.Forms.Platform.Android
UpdateBackgroundColor();
else if (e.PropertyName == VisualElement.InputTransparentProperty.PropertyName)
InputTransparent = Element.InputTransparent;
+ else if (e.PropertyName == Accessibility.HintProperty.PropertyName)
+ SetContentDescription();
+ else if (e.PropertyName == Accessibility.NameProperty.PropertyName)
+ SetContentDescription();
+ else if (e.PropertyName == Accessibility.IsInAccessibleTreeProperty.PropertyName)
+ SetFocusable();
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
@@ -331,6 +344,62 @@ namespace Xamarin.Forms.Platform.Android
ContentDescription = id;
}
+ protected virtual void SetContentDescription()
+ {
+ if (Element == null)
+ return;
+
+ if (SetHint())
+ return;
+
+ if (_defaultContentDescription == null)
+ _defaultContentDescription = ContentDescription;
+
+ var elemValue = string.Join(" ", (string)Element.GetValue(Accessibility.NameProperty), (string)Element.GetValue(Accessibility.HintProperty));
+
+ if (!string.IsNullOrWhiteSpace(elemValue))
+ ContentDescription = elemValue;
+ else
+ ContentDescription = _defaultContentDescription;
+ }
+
+ protected virtual void SetFocusable()
+ {
+ if (Element == null)
+ return;
+
+ if (!_defaultFocusable.HasValue)
+ _defaultFocusable = Focusable;
+
+ Focusable = (bool)((bool?)Element.GetValue(Accessibility.IsInAccessibleTreeProperty) ?? _defaultFocusable);
+ }
+
+ protected virtual bool SetHint()
+ {
+ if (Element == null)
+ return false;
+
+ var textView = this as global::Android.Widget.TextView;
+ if (textView == null)
+ return false;
+
+ // Let the specified Title/Placeholder take precedence, but don't set the ContentDescription (won't work anyway)
+ if (((Element as Picker)?.Title ?? (Element as Entry)?.Placeholder ?? (Element as EntryCell)?.Placeholder) != null)
+ return true;
+
+ if (_defaultHint == null)
+ _defaultHint = textView.Hint;
+
+ var elemValue = string.Join(". ", (string)Element.GetValue(Accessibility.NameProperty), (string)Element.GetValue(Accessibility.HintProperty));
+
+ if (!string.IsNullOrWhiteSpace(elemValue))
+ textView.Hint = elemValue;
+ else
+ textView.Hint = _defaultHint;
+
+ return true;
+ }
+
protected void SetPackager(VisualElementPackager packager)
{
_packager = packager;
@@ -357,6 +426,14 @@ namespace Xamarin.Forms.Platform.Android
UpdateGestureRecognizers();
}
+ void IVisualElementRenderer.SetLabelFor(int? id)
+ {
+ if (_defaultLabelFor == null)
+ _defaultLabelFor = LabelFor;
+
+ LabelFor = (int)(id ?? _defaultLabelFor);
+ }
+
void SubscribeGestureRecognizers(VisualElement element)
{
var view = element as View;
diff --git a/Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs b/Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs
index e024b235..4a7fe033 100644
--- a/Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs
+++ b/Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs
@@ -112,6 +112,11 @@ namespace Xamarin.Forms.Platform.UWP
return new SizeRequest(new Size(size.Width, size.Height));
}
+ UIElement IVisualElementRenderer.GetNativeElement()
+ {
+ return Control;
+ }
+
public void SetElement(VisualElement element)
{
MasterDetailPage old = Element;
diff --git a/Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs b/Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs
index 02b73c94..c278e394 100644
--- a/Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs
+++ b/Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs
@@ -122,7 +122,12 @@ namespace Xamarin.Forms.Platform.UWP
return new SizeRequest(result);
}
- public void SetElement(VisualElement element)
+ UIElement IVisualElementRenderer.GetNativeElement()
+ {
+ return Control;
+ }
+
+ public void SetElement(VisualElement element)
{
if (element != null && !(element is TabbedPage))
throw new ArgumentException("Element must be a TabbedPage", "element");
diff --git a/Xamarin.Forms.Platform.WinRT.Phone/TabbedPageRenderer.cs b/Xamarin.Forms.Platform.WinRT.Phone/TabbedPageRenderer.cs
index 25c4d9ed..fe660ff9 100644
--- a/Xamarin.Forms.Platform.WinRT.Phone/TabbedPageRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT.Phone/TabbedPageRenderer.cs
@@ -135,6 +135,11 @@ namespace Xamarin.Forms.Platform.WinRT
return new SizeRequest(result);
}
+ UIElement IVisualElementRenderer.GetNativeElement()
+ {
+ return null;
+ }
+
public void Dispose()
{
Dispose(true);
diff --git a/Xamarin.Forms.Platform.WinRT.Tablet/TabbedPageRenderer.cs b/Xamarin.Forms.Platform.WinRT.Tablet/TabbedPageRenderer.cs
index 2cfc2411..2ac48dda 100644
--- a/Xamarin.Forms.Platform.WinRT.Tablet/TabbedPageRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT.Tablet/TabbedPageRenderer.cs
@@ -144,6 +144,11 @@ namespace Xamarin.Forms.Platform.WinRT
return new SizeRequest(result);
}
+ UIElement IVisualElementRenderer.GetNativeElement()
+ {
+ return null;
+ }
+
public void Dispose()
{
Dispose(true);
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 e8e3da41..185737aa 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)
diff --git a/Xamarin.Forms.Platform.iOS/Renderers/ButtonRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/ButtonRenderer.cs
index 68d4702d..3e99cd5d 100644
--- a/Xamarin.Forms.Platform.iOS/Renderers/ButtonRenderer.cs
+++ b/Xamarin.Forms.Platform.iOS/Renderers/ButtonRenderer.cs
@@ -86,6 +86,21 @@ namespace Xamarin.Forms.Platform.iOS
UpdateImage();
}
+ protected override void SetAccessibilityLabel()
+ {
+ // If we have not specified an AccessibilityLabel and the AccessibiltyLabel is current bound to the Title,
+ // exit this method so we don't set the AccessibilityLabel value and break the binding.
+ // This may pose a problem for users who want to explicitly set the AccessibilityLabel to null, but this
+ // will prevent us from inadvertently breaking UI Tests that are using Query.Marked to get the dynamic Title
+ // of the Button.
+
+ var elemValue = (string)Element?.GetValue(Accessibility.NameProperty);
+ if (string.IsNullOrWhiteSpace(elemValue) && Control?.AccessibilityLabel == Control?.Title(UIControlState.Normal))
+ return;
+
+ base.SetAccessibilityLabel();
+ }
+
void OnButtonTouchUpInside(object sender, EventArgs eventArgs)
{
((IButtonController)Element)?.SendClicked();
diff --git a/Xamarin.Forms.Platform.iOS/Renderers/LabelRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/LabelRenderer.cs
index 5fde3519..4cf3be92 100644
--- a/Xamarin.Forms.Platform.iOS/Renderers/LabelRenderer.cs
+++ b/Xamarin.Forms.Platform.iOS/Renderers/LabelRenderer.cs
@@ -121,6 +121,23 @@ namespace Xamarin.Forms.Platform.MacOS
UpdateLineBreakMode();
}
+#if __MOBILE__
+ protected override void SetAccessibilityLabel()
+ {
+ // If we have not specified an AccessibilityLabel and the AccessibiltyLabel is current bound to the Text,
+ // exit this method so we don't set the AccessibilityLabel value and break the binding.
+ // This may pose a problem for users who want to explicitly set the AccessibilityLabel to null, but this
+ // will prevent us from inadvertently breaking UI Tests that are using Query.Marked to get the dynamic Text
+ // of the Label.
+
+ var elemValue = (string)Element?.GetValue(Accessibility.NameProperty);
+ if (string.IsNullOrWhiteSpace(elemValue) && Control?.AccessibilityLabel == Control?.Text)
+ return;
+
+ base.SetAccessibilityLabel();
+ }
+#endif
+
protected override void SetBackgroundColor(Color color)
{
#if __MOBILE__
diff --git a/Xamarin.Forms.Platform.iOS/ViewRenderer.cs b/Xamarin.Forms.Platform.iOS/ViewRenderer.cs
index 01f8e06a..2cf9f754 100644
--- a/Xamarin.Forms.Platform.iOS/ViewRenderer.cs
+++ b/Xamarin.Forms.Platform.iOS/ViewRenderer.cs
@@ -25,6 +25,11 @@ namespace Xamarin.Forms.Platform.MacOS
public abstract class ViewRenderer<TView, TNativeView> : VisualElementRenderer<TView> where TView : View where TNativeView : NativeView
{
+#if __MOBILE__
+ string _defaultAccessibilityLabel;
+ string _defaultAccessibilityHint;
+ bool? _defaultIsAccessibilityElement;
+#endif
NativeColor _defaultColor;
public TNativeView Control { get; private set; }
@@ -110,7 +115,59 @@ namespace Xamarin.Forms.Platform.MacOS
base.OnRegisterEffect(effect);
effect.Control = Control;
}
+#if __MOBILE__
+ protected override void SetAccessibilityHint()
+ {
+ if (Control == null)
+ {
+ base.SetAccessibilityHint();
+ return;
+ }
+
+ if (Element == null)
+ return;
+
+ if (_defaultAccessibilityHint == null)
+ _defaultAccessibilityHint = Control.AccessibilityHint;
+
+ Control.AccessibilityHint = (string)Element.GetValue(Accessibility.HintProperty) ?? _defaultAccessibilityHint;
+
+ }
+
+ protected override void SetAccessibilityLabel()
+ {
+ if (Control == null)
+ {
+ base.SetAccessibilityLabel();
+ return;
+ }
+
+ if (Element == null)
+ return;
+
+ if (_defaultAccessibilityLabel == null)
+ _defaultAccessibilityLabel = Control.AccessibilityLabel;
+
+ Control.AccessibilityLabel = (string)Element.GetValue(Accessibility.NameProperty) ?? _defaultAccessibilityLabel;
+ }
+
+ protected override void SetIsAccessibilityElement()
+ {
+ if (Control == null)
+ {
+ base.SetIsAccessibilityElement();
+ return;
+ }
+ if (Element == null)
+ return;
+
+ if (!_defaultIsAccessibilityElement.HasValue)
+ _defaultIsAccessibilityElement = Control.IsAccessibilityElement;
+
+ Control.IsAccessibilityElement = (bool)((bool?)Element.GetValue(Accessibility.IsInAccessibleTreeProperty) ?? _defaultIsAccessibilityElement);
+ }
+#endif
protected override void SetAutomationId(string id)
{
if (Control == null)
diff --git a/Xamarin.Forms.Platform.iOS/VisualElementRenderer.cs b/Xamarin.Forms.Platform.iOS/VisualElementRenderer.cs
index 0e7af2a5..57c9ab12 100644
--- a/Xamarin.Forms.Platform.iOS/VisualElementRenderer.cs
+++ b/Xamarin.Forms.Platform.iOS/VisualElementRenderer.cs
@@ -36,6 +36,11 @@ namespace Xamarin.Forms.Platform.MacOS
readonly List<EventHandler<VisualElementChangedEventArgs>> _elementChangedHandlers = new List<EventHandler<VisualElementChangedEventArgs>>();
readonly PropertyChangedEventHandler _propertyChangedHandler;
+#if __MOBILE__
+ string _defaultAccessibilityLabel;
+ string _defaultAccessibilityHint;
+ bool? _defaultIsAccessibilityElement;
+#endif
EventTracker _events;
VisualElementRendererFlags _flags = VisualElementRendererFlags.AutoPackage | VisualElementRendererFlags.AutoTrack;
@@ -177,6 +182,7 @@ namespace Xamarin.Forms.Platform.MacOS
}
element.PropertyChanged += _propertyChangedHandler;
+
}
OnElementChanged(new ElementChangedEventArgs<TElement>(oldElement, element));
@@ -188,6 +194,11 @@ namespace Xamarin.Forms.Platform.MacOS
if (Element != null && !string.IsNullOrEmpty(Element.AutomationId))
SetAutomationId(Element.AutomationId);
+#if __MOBILE__
+ SetAccessibilityLabel();
+ SetAccessibilityHint();
+ SetIsAccessibilityElement();
+#endif
}
#if __MOBILE__
@@ -269,6 +280,12 @@ namespace Xamarin.Forms.Platform.MacOS
#if __MOBILE__
else if (e.PropertyName == PlatformConfiguration.iOSSpecific.VisualElement.BlurEffectProperty.PropertyName)
SetBlur((BlurEffectStyle)Element.GetValue(PlatformConfiguration.iOSSpecific.VisualElement.BlurEffectProperty));
+ else if (e.PropertyName == Accessibility.HintProperty.PropertyName)
+ SetAccessibilityHint();
+ else if (e.PropertyName == Accessibility.NameProperty.PropertyName)
+ SetAccessibilityLabel();
+ else if (e.PropertyName == Accessibility.IsInAccessibleTreeProperty.PropertyName)
+ SetIsAccessibilityElement();
#endif
}
@@ -277,6 +294,40 @@ namespace Xamarin.Forms.Platform.MacOS
effect.Container = this;
}
+#if __MOBILE__
+ protected virtual void SetAccessibilityHint()
+ {
+ if (Element == null)
+ return;
+
+ if (_defaultAccessibilityHint == null)
+ _defaultAccessibilityHint = AccessibilityHint;
+
+ AccessibilityHint = (string)Element.GetValue(Accessibility.HintProperty) ?? _defaultAccessibilityHint;
+ }
+
+ protected virtual void SetAccessibilityLabel()
+ {
+ if (Element == null)
+ return;
+
+ if (_defaultAccessibilityLabel == null)
+ _defaultAccessibilityLabel = AccessibilityLabel;
+
+ AccessibilityLabel = (string)Element.GetValue(Accessibility.NameProperty) ?? _defaultAccessibilityLabel;
+ }
+
+ protected virtual void SetIsAccessibilityElement()
+ {
+ if (Element == null)
+ return;
+
+ if (!_defaultIsAccessibilityElement.HasValue)
+ _defaultIsAccessibilityElement = IsAccessibilityElement;
+
+ IsAccessibilityElement = (bool)((bool?)Element.GetValue(Accessibility.IsInAccessibleTreeProperty) ?? _defaultIsAccessibilityElement);
+ }
+#endif
protected virtual void SetAutomationId(string id)
{
AccessibilityIdentifier = id;
@@ -286,11 +337,11 @@ namespace Xamarin.Forms.Platform.MacOS
{
if (color == Color.Default)
#if __MOBILE__
-
+
BackgroundColor = _defaultColor;
else
BackgroundColor = color.ToUIColor();
-
+
#else
Layer.BackgroundColor = _defaultColor.CGColor;
else
diff --git a/docs/Xamarin.Forms.Core/Xamarin.Forms/Accessibility.xml b/docs/Xamarin.Forms.Core/Xamarin.Forms/Accessibility.xml
new file mode 100644
index 00000000..c18c73e6
--- /dev/null
+++ b/docs/Xamarin.Forms.Core/Xamarin.Forms/Accessibility.xml
@@ -0,0 +1,91 @@
+<Type Name="Accessibility" FullName="Xamarin.Forms.Accessibility">
+ <TypeSignature Language="C#" Value="public class Accessibility" />
+ <TypeSignature Language="ILAsm" Value=".class public auto ansi beforefieldinit Accessibility extends System.Object" />
+ <AssemblyInfo>
+ <AssemblyName>Xamarin.Forms.Core</AssemblyName>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <Base>
+ <BaseTypeName>System.Object</BaseTypeName>
+ </Base>
+ <Interfaces />
+ <Docs>
+ <summary>To be added.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ <Members>
+ <Member MemberName=".ctor">
+ <MemberSignature Language="C#" Value="public Accessibility ();" />
+ <MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor() cil managed" />
+ <MemberType>Constructor</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <Parameters />
+ <Docs>
+ <summary>To be added.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
+ <Member MemberName="HintProperty">
+ <MemberSignature Language="C#" Value="public static readonly Xamarin.Forms.BindableProperty HintProperty;" />
+ <MemberSignature Language="ILAsm" Value=".field public static initonly class Xamarin.Forms.BindableProperty HintProperty" />
+ <MemberType>Field</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <ReturnValue>
+ <ReturnType>Xamarin.Forms.BindableProperty</ReturnType>
+ </ReturnValue>
+ <Docs>
+ <summary>To be added.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
+ <Member MemberName="IsInAccessibleTreeProperty">
+ <MemberSignature Language="C#" Value="public static readonly Xamarin.Forms.BindableProperty IsInAccessibleTreeProperty;" />
+ <MemberSignature Language="ILAsm" Value=".field public static initonly class Xamarin.Forms.BindableProperty IsInAccessibleTreeProperty" />
+ <MemberType>Field</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <ReturnValue>
+ <ReturnType>Xamarin.Forms.BindableProperty</ReturnType>
+ </ReturnValue>
+ <Docs>
+ <summary>To be added.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
+ <Member MemberName="LabeledByProperty">
+ <MemberSignature Language="C#" Value="public static readonly Xamarin.Forms.BindableProperty LabeledByProperty;" />
+ <MemberSignature Language="ILAsm" Value=".field public static initonly class Xamarin.Forms.BindableProperty LabeledByProperty" />
+ <MemberType>Field</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <ReturnValue>
+ <ReturnType>Xamarin.Forms.BindableProperty</ReturnType>
+ </ReturnValue>
+ <Docs>
+ <summary>To be added.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
+ <Member MemberName="NameProperty">
+ <MemberSignature Language="C#" Value="public static readonly Xamarin.Forms.BindableProperty NameProperty;" />
+ <MemberSignature Language="ILAsm" Value=".field public static initonly class Xamarin.Forms.BindableProperty NameProperty" />
+ <MemberType>Field</MemberType>
+ <AssemblyInfo>
+ <AssemblyVersion>2.0.0.0</AssemblyVersion>
+ </AssemblyInfo>
+ <ReturnValue>
+ <ReturnType>Xamarin.Forms.BindableProperty</ReturnType>
+ </ReturnValue>
+ <Docs>
+ <summary>To be added.</summary>
+ <remarks>To be added.</remarks>
+ </Docs>
+ </Member>
+ </Members>
+</Type>