From d1bf93be200b3d3c48d0d292bf455f444485d8f9 Mon Sep 17 00:00:00 2001 From: Paul DiPietro Date: Tue, 12 Sep 2017 07:54:22 -0400 Subject: [PATCH] [UWP] Use ItemClick to re-enable use of enter key for selection on ListView (#1133) --- .../Bugzilla59248.cs | 57 +++++++++++++++++++ ...rin.Forms.Controls.Issues.Shared.projitems | 1 + .../ListViewRenderer.cs | 48 ++++------------ 3 files changed, 68 insertions(+), 38 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla59248.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla59248.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla59248.cs new file mode 100644 index 00000000000..96a80296712 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla59248.cs @@ -0,0 +1,57 @@ +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +#if UITEST +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 59248, "[UWP] ItemTapped event is not fired when keyboard Enter Pressed on ListView", PlatformAffected.UWP)] + public class Bugzilla59248 : TestContentPage + { + protected override void Init() + { + var selectedItem = new Label { Text = "SelectedItem" }; + var list = new ListView + { + ItemsSource = new string[] { "A", "B", "C" }, + ItemTemplate = new DataTemplate(() => + { + var view = new ViewCell(); + view.View = new StackLayout + { + Children = + { + new Label { Text = "Label" }, + new Button { Text = "Click for alert", Command = new Command(() => DisplayAlert("Clicked the button in the listview item", "Ok", "Cancel"))} + } + }; + return view; + }) + }; + list.ItemTapped += List_ItemTapped; + list.ItemSelected += (s, e) => + { + selectedItem.Text = list.SelectedItem == null ? "None" : list.SelectedItem.ToString(); + }; + + Content = new StackLayout + { + Children = + { + list, + selectedItem + } + }; + } + + private void List_ItemTapped(object sender, ItemTappedEventArgs e) + { + if (e.Item != null) + DisplayAlert("Tapped: " + e.Item, "Ok", "Cancel"); + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 07cea4fda4b..6b128ca8c17 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -216,6 +216,7 @@ + diff --git a/Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs b/Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs index 0fb5af80fba..33525bc1fad 100644 --- a/Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs +++ b/Xamarin.Forms.Platform.WinRT/ListViewRenderer.cs @@ -72,10 +72,8 @@ protected override void OnElementChanged(ElementChangedEventArgs e) GroupStyleSelector = (GroupStyleSelector)WApp.Current.Resources["ListViewGroupSelector"] }; - // In order to support tapping on elements within a list item, we handle - // ListView.Tapped (which can be handled by child elements in the list items - // and prevented from bubbling up) rather than ListView.ItemClick - List.Tapped += ListOnTapped; + List.IsItemClickEnabled = true; + List.ItemClick += OnListItemClicked; List.SelectionChanged += OnControlSelectionChanged; @@ -137,8 +135,7 @@ protected override void Dispose(bool disposing) { if (List != null) { - List.Tapped -= ListOnTapped; - + List.ItemClick -= OnListItemClicked; List.SelectionChanged -= OnControlSelectionChanged; List.DataContext = null; @@ -437,32 +434,6 @@ void OnElementItemSelected(object sender, SelectedItemChangedEventArgs e) List.SelectedIndex = index; } - void ListOnTapped(object sender, TappedRoutedEventArgs args) - { - var orig = args.OriginalSource as DependencyObject; - int index = -1; - - // Work our way up the tree until we find the actual list item - // the user tapped on - while (orig != null && orig != List) - { - var lv = orig as ListViewItem; - - if (lv != null) - { - index = TemplatedItemsView.TemplatedItems.GetGlobalIndexOfItem(lv.Content); - break; - } - - orig = VisualTreeHelper.GetParent(orig); - } - - if (index > -1) - { - OnListItemClicked(index); - } - } - void OnListItemClicked(int index) { #if !WINDOWS_UWP @@ -504,6 +475,12 @@ void OnListItemClicked(int index) #endif } + void OnListItemClicked(object sender, ItemClickEventArgs e) + { + if (e.ClickedItem != null) + OnListItemClicked(((WListView)e.OriginalSource).Items.IndexOf(e.ClickedItem)); + } + void OnControlSelectionChanged(object sender, SelectionChangedEventArgs e) { RestorePreviousSelectedVisual(); @@ -533,13 +510,8 @@ void OnControlSelectionChanged(object sender, SelectionChangedEventArgs e) } } #endif - - // A11y: Tapped event will not be routed when Narrator is active, so we need to handle it here. - // Also handles keyboard selection. - // Default UWP behavior is that items are selected when you navigate to them via the arrow keys - // and deselected with the space bar, so this will remain the same. if (Element.SelectedItem != List.SelectedItem) - OnListItemClicked(List.SelectedIndex); + ((IElementController)Element).SetValueFromRenderer(ListView.SelectedItemProperty, List.SelectedItem); } FrameworkElement FindElement(object cell)