diff options
| -rw-r--r-- | ApartmentManager/ApartmentManager/ApartmentManager.csproj | 1 | ||||
| -rw-r--r-- | ApartmentManager/ApartmentManager/Controls/NavMenuListView.cs | 120 | 
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)' < '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  |