From 6b46f1db25cb231d51a3e77f0146b2af7e464464 Mon Sep 17 00:00:00 2001 From: marcinzelent Date: Fri, 28 Apr 2017 17:12:37 +0200 Subject: Added hamburger menu. --- ApartmentAdmin | 1 - .../ApartmentManager/ApartmentManager.csproj | 9 ++ ApartmentManager/ApartmentManager/App.xaml | 2 +- ApartmentManager/ApartmentManager/AppShell.xaml | 137 ++++++++++++++++++ ApartmentManager/ApartmentManager/AppShell.xaml.cs | 159 +++++++++++++++++++++ .../ApartmentManager/Controls/NavMenuListView.cs | 120 ++++++++++++++++ .../ApartmentManager/Model/NavMenuItem.cs | 60 ++++++++ HousingDatabase.ldf | Bin 8388608 -> 8388608 bytes HousingDatabase.mdf | Bin 8388608 -> 8388608 bytes 9 files changed, 486 insertions(+), 2 deletions(-) delete mode 160000 ApartmentAdmin create mode 100644 ApartmentManager/ApartmentManager/AppShell.xaml create mode 100644 ApartmentManager/ApartmentManager/AppShell.xaml.cs create mode 100644 ApartmentManager/ApartmentManager/Controls/NavMenuListView.cs create mode 100644 ApartmentManager/ApartmentManager/Model/NavMenuItem.cs diff --git a/ApartmentAdmin b/ApartmentAdmin deleted file mode 160000 index 9345c7a..0000000 --- a/ApartmentAdmin +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9345c7a897c4f0f195c80f117850b8fec1f91afc diff --git a/ApartmentManager/ApartmentManager/ApartmentManager.csproj b/ApartmentManager/ApartmentManager/ApartmentManager.csproj index b08d130..b8fd095 100644 --- a/ApartmentManager/ApartmentManager/ApartmentManager.csproj +++ b/ApartmentManager/ApartmentManager/ApartmentManager.csproj @@ -95,8 +95,13 @@ App.xaml + + AppShell.xaml + + + @@ -124,6 +129,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/ApartmentManager/ApartmentManager/App.xaml b/ApartmentManager/ApartmentManager/App.xaml index dc08cec..e4c9342 100644 --- a/ApartmentManager/ApartmentManager/App.xaml +++ b/ApartmentManager/ApartmentManager/App.xaml @@ -3,6 +3,6 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ApartmentManager" - RequestedTheme="Dark"> + RequestedTheme="Light"> diff --git a/ApartmentManager/ApartmentManager/AppShell.xaml b/ApartmentManager/ApartmentManager/AppShell.xaml new file mode 100644 index 0000000..28d40e3 --- /dev/null +++ b/ApartmentManager/ApartmentManager/AppShell.xaml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ApartmentManager/ApartmentManager/AppShell.xaml.cs b/ApartmentManager/ApartmentManager/AppShell.xaml.cs new file mode 100644 index 0000000..ed86a46 --- /dev/null +++ b/ApartmentManager/ApartmentManager/AppShell.xaml.cs @@ -0,0 +1,159 @@ +using ApartmentManager.Controls; +using ApartmentManager.Model; +using ApartmentManager.View; +using System.Collections.Generic; +using System.Linq; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Navigation; + +namespace ApartmentManager +{ + /// + /// The "chrome" layer of the app that provides top-level navigation with + /// proper keyboarding navigation. + /// + public sealed partial class AppShell : Page + { + // Declare the top level nav items + private List navMenuItems = new List( + new[] + { + new NavMenuItem() + { + Symbol = Symbol.Home, + Label = "Home", + DestPage = typeof(LoginPage), + IsSelected = true + } + }); + + public static AppShell Current = null; + + /// + /// Initializes a new instance of the AppShell, sets the static 'Current' reference, + /// adds callbacks for Back requests and changes in the SplitView's DisplayMode, and + /// provide the nav menu list with the data to display. + /// + public AppShell() + { + InitializeComponent(); + + List topNavMenuItems = navMenuItems.GetRange(0, 3); + List bottomNavMenuItems = navMenuItems.GetRange(3, 2); + + NavMenuList.ItemsSource = topNavMenuItems; + NavMenuList2.ItemsSource = bottomNavMenuItems; + } + + public Frame AppFrame { get { return Frame; } } + + #region Navigation + + /// + /// Navigate to the Page for the selected . + /// + /// + /// + private void NavMenuList_ItemInvoked(object sender, ListViewItem listViewItem) + { + foreach (var i in navMenuItems) + { + i.IsSelected = false; + } + + var item = (NavMenuItem)((NavMenuListView)sender).ItemFromContainer(listViewItem); + + if (item != null) + { + item.IsSelected = true; + if (item.DestPage != null && + item.DestPage != AppFrame.CurrentSourcePageType) + { + AppFrame.Navigate(item.DestPage, item.Arguments); + } + } + } + + /// + /// Ensures the nav menu reflects reality when navigation is triggered outside of + /// the nav menu buttons. + /// + /// + /// + private void OnNavigatingToPage(object sender, NavigatingCancelEventArgs e) + { + if (e.NavigationMode == NavigationMode.Back) + { + var item = (from p in navMenuItems where p.DestPage == e.SourcePageType select p).SingleOrDefault(); + if (item == null && AppFrame.BackStackDepth > 0) + { + // In cases where a page drills into sub-pages then we'll highlight the most recent + // navigation menu item that appears in the BackStack + foreach (var entry in this.AppFrame.BackStack.Reverse()) + { + item = (from p in navMenuItems where p.DestPage == entry.SourcePageType select p).SingleOrDefault(); + if (item != null) + break; + } + } + + foreach (var i in navMenuItems) + { + i.IsSelected = false; + } + if (item != null) + { + item.IsSelected = true; + } + + var container = (ListViewItem)NavMenuList.ContainerFromItem(item); + + // While updating the selection state of the item prevent it from taking keyboard focus. If a + // user is invoking the back button via the keyboard causing the selected nav menu item to change + // then focus will remain on the back button. + if (container != null) container.IsTabStop = false; + NavMenuList.SetSelectedItem(container); + if (container != null) container.IsTabStop = true; + } + } + + #endregion Navigation + + /// + /// Public method to allow pages to open SplitView's pane. + /// Used for custom app shortcuts like navigating left from page's left-most item + /// + public void OpenNavePane() + { + TogglePaneButton.IsChecked = true; + } + + public void MakeStackPanel1Visible() + { + StackPanel1.Visibility = Visibility.Visible; + StackPanel2.Visibility = Visibility.Collapsed; + } + + public void MakeStackPanel2Visible() + { + StackPanel1.Visibility = Visibility.Collapsed; + StackPanel2.Visibility = Visibility.Visible; + } + + private void GoToLoginView(object sender, RoutedEventArgs e) + { + Frame.Navigate(typeof(LoginView)); + } + + private void GoToCreateUserView(object sender, RoutedEventArgs e) + { + Frame.Navigate(typeof(CreateUserView)); + } + + private void GoToUserView(object sender, RoutedEventArgs e) + { + Frame.Navigate(typeof(UserView)); + } + } +} \ No newline at end of file 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 +{ + /// + /// A specialized ListView to represent the items in the navigation menu. + /// + /// + /// 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. + /// + 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); + } + } + } + + /// + /// Mark the as selected and ensures everything else is not. + /// If the is null then everything is unselected. + /// + /// + 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; + } + } + } + + /// + /// Occurs when an item has been selected + /// + public event EventHandler 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 diff --git a/ApartmentManager/ApartmentManager/Model/NavMenuItem.cs b/ApartmentManager/ApartmentManager/Model/NavMenuItem.cs new file mode 100644 index 0000000..d71d198 --- /dev/null +++ b/ApartmentManager/ApartmentManager/Model/NavMenuItem.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace ApartmentManager.Model +{ + /// + /// Data to represent an item in the nav menu. + /// + public class NavMenuItem : INotifyPropertyChanged + { + public string Label { get; set; } + public Symbol Symbol { get; set; } + + public char SymbolAsChar + { + get + { + return (char)this.Symbol; + } + } + + private bool _isSelected; + + public bool IsSelected + { + get { return _isSelected; } + set + { + _isSelected = value; + SelectedVis = value ? Visibility.Visible : Visibility.Collapsed; + this.OnPropertyChanged("IsSelected"); + } + } + + private Visibility _selectedVis = Visibility.Collapsed; + + public Visibility SelectedVis + { + get { return _selectedVis; } + set + { + _selectedVis = value; + this.OnPropertyChanged("SelectedVis"); + } + } + + public Type DestPage { get; set; } + public object Arguments { get; set; } + + public event PropertyChangedEventHandler PropertyChanged = delegate { }; + + public void OnPropertyChanged(string propertyName) + { + // Raise the PropertyChanged event, passing the name of the property whose value has changed. + this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } +} \ No newline at end of file diff --git a/HousingDatabase.ldf b/HousingDatabase.ldf index 17d07d1..d488ec6 100644 Binary files a/HousingDatabase.ldf and b/HousingDatabase.ldf differ diff --git a/HousingDatabase.mdf b/HousingDatabase.mdf index d8ee802..cd5d6e1 100644 Binary files a/HousingDatabase.mdf and b/HousingDatabase.mdf differ -- cgit v1.2.3