aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ApartmentManager/ApartmentManager/ApartmentManager.csproj1
-rw-r--r--ApartmentManager/ApartmentManager/Controls/NavMenuListView.cs120
2 files changed, 121 insertions, 0 deletions
diff --git a/ApartmentManager/ApartmentManager/ApartmentManager.csproj b/ApartmentManager/ApartmentManager/ApartmentManager.csproj
index 601b96b..1b3c63e 100644
--- a/ApartmentManager/ApartmentManager/ApartmentManager.csproj
+++ b/ApartmentManager/ApartmentManager/ApartmentManager.csproj
@@ -279,6 +279,7 @@
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
+ <ItemGroup />
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
diff --git a/ApartmentManager/ApartmentManager/Controls/NavMenuListView.cs b/ApartmentManager/ApartmentManager/Controls/NavMenuListView.cs
new file mode 100644
index 0000000..9591ad1
--- /dev/null
+++ b/ApartmentManager/ApartmentManager/Controls/NavMenuListView.cs
@@ -0,0 +1,120 @@
+using System;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Media.Animation;
+
+namespace ApartmentManager.Controls
+{
+ /// <summary>
+ /// A specialized ListView to represent the items in the navigation menu.
+ /// </summary>
+ /// <remarks>
+ /// This class handles the following:
+ /// 1. Sizes the panel that hosts the items so they fit in the hosting pane. Otherwise, the keyboard
+ /// may appear cut off on one side b/c the Pane clips instead of affecting layout.
+ /// 2. Provides a single selection experience where keyboard focus can move without changing selection.
+ /// Both the 'Space' and 'Enter' keys will trigger selection. The up/down arrow keys can move
+ /// keyboard focus without triggering selection. This is different than the default behavior when
+ /// SelectionMode == Single. The default behavior for a ListView in single selection requires using
+ /// the Ctrl + arrow key to move keyboard focus without triggering selection. Users won't expect
+ /// this type of keyboarding model on the nav menu.
+ /// </remarks>
+ public class NavMenuListView : ListView
+ {
+ private SplitView _splitViewHost;
+
+ public NavMenuListView()
+ {
+ SelectionMode = ListViewSelectionMode.Single;
+ IsItemClickEnabled = true;
+ ItemClick += ItemClickedHandler;
+
+ // Locate the hosting SplitView control
+ Loaded += (s, a) =>
+ {
+ var parent = VisualTreeHelper.GetParent(this);
+ while (parent != null && !(parent is SplitView))
+ {
+ parent = VisualTreeHelper.GetParent(parent);
+ }
+
+ if (parent != null)
+ {
+ _splitViewHost = parent as SplitView;
+ }
+ };
+ }
+
+ protected override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ // Remove the entrance animation on the item containers.
+ for (int i = 0; i < ItemContainerTransitions.Count; i++)
+ {
+ if (ItemContainerTransitions[i] is EntranceThemeTransition)
+ {
+ ItemContainerTransitions.RemoveAt(i);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Mark the <paramref name="item"/> as selected and ensures everything else is not.
+ /// If the <paramref name="item"/> is null then everything is unselected.
+ /// </summary>
+ /// <param name="item"></param>
+ public void SetSelectedItem(ListViewItem item)
+ {
+ int index = -1;
+ if (item != null)
+ {
+ index = IndexFromContainer(item);
+ }
+
+ for (int i = 0; i < Items.Count; i++)
+ {
+ var lvi = (ListViewItem)ContainerFromIndex(i);
+ if (i != index)
+ {
+ lvi.IsSelected = false;
+ }
+ else if (i == index)
+ {
+ lvi.IsSelected = true;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Occurs when an item has been selected
+ /// </summary>
+ public event EventHandler<ListViewItem> ItemInvoked;
+
+ private void ItemClickedHandler(object sender, ItemClickEventArgs e)
+ {
+ // Triggered when the item is selected using something other than a keyboard
+ var item = ContainerFromItem(e.ClickedItem);
+ InvokeItem(item);
+ }
+
+ private void InvokeItem(object focusedItem)
+ {
+ SetSelectedItem(focusedItem as ListViewItem);
+ ItemInvoked?.Invoke(this, focusedItem as ListViewItem);
+
+ if (_splitViewHost.IsPaneOpen && (
+ _splitViewHost.DisplayMode == SplitViewDisplayMode.CompactOverlay ||
+ _splitViewHost.DisplayMode == SplitViewDisplayMode.Overlay))
+ {
+ _splitViewHost.IsPaneOpen = false;
+ }
+
+ if (focusedItem is ListViewItem)
+ {
+ ((ListViewItem)focusedItem).Focus(FocusState.Programmatic);
+ }
+ }
+ }
+} \ No newline at end of file