diff options
m--------- | ApartmentAdmin | 0 | ||||
-rw-r--r-- | ApartmentManager/ApartmentManager/ApartmentManager.csproj | 13 | ||||
-rw-r--r-- | ApartmentManager/ApartmentManager/AppShell.xaml | 137 | ||||
-rw-r--r-- | ApartmentManager/ApartmentManager/AppShell.xaml.cs | 159 | ||||
-rw-r--r-- | ApartmentManager/ApartmentManager/Controls/NavMenuListView.cs | 120 | ||||
-rw-r--r-- | ApartmentManager/ApartmentManager/Model/NavMenuItem.cs | 60 | ||||
-rw-r--r-- | HousingDatabase.ldf | bin | 8388608 -> 8388608 bytes | |||
-rw-r--r-- | HousingDatabase.mdf | bin | 8388608 -> 8388608 bytes |
8 files changed, 481 insertions, 8 deletions
diff --git a/ApartmentAdmin b/ApartmentAdmin deleted file mode 160000 -Subproject f4d7fc3fa885184fb073fbae2aea28a476a85b8 diff --git a/ApartmentManager/ApartmentManager/ApartmentManager.csproj b/ApartmentManager/ApartmentManager/ApartmentManager.csproj index 2fec108..3768365 100644 --- a/ApartmentManager/ApartmentManager/ApartmentManager.csproj +++ b/ApartmentManager/ApartmentManager/ApartmentManager.csproj @@ -95,8 +95,13 @@ <Compile Include="App.xaml.cs"> <DependentUpon>App.xaml</DependentUpon> </Compile> + <Compile Include="AppShell.xaml.cs"> + <DependentUpon>AppShell.xaml</DependentUpon> + </Compile> <Compile Include="Common\RelayCommand.cs" /> + <Compile Include="Controls\NavMenuListView.cs" /> <Compile Include="Model\Class1.cs" /> + <Compile Include="Model\NavMenuItem.cs" /> <Compile Include="Persistency\Persistency.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="View\ApartmentPage.xaml.cs"> @@ -133,14 +138,6 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </ApplicationDefinition> - <Page Include="View\ApartmentPage.xaml"> - <SubType>Designer</SubType> - <Generator>MSBuild:Compile</Generator> - </Page> - <Page Include="View\ApartmentPlanPage.xaml"> - <SubType>Designer</SubType> - <Generator>MSBuild:Compile</Generator> - </Page> <Page Include="View\LoginPage.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> 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 @@ +<Page x:Name="Root" + x:Class="ApartmentManager.AppShell" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="using:ApartmentManager" + xmlns:controls="using:ApartmentManager.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:model="using:ApartmentManager.Model" + xmlns:viewModel="using:ApartmentManager.ViewModel" + Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" + TabNavigation="Cycle" + mc:Ignorable="d"> + + <!-- Using a Page as the root for the app provides a design time experience as well as ensures that + when it runs on Mobile the app content won't appear under the system's StatusBar which is visible + by default with a transparent background. It will also take into account the presence of software + navigation buttons if they appear on a device. An app can opt-out by switching to UseCoreWindow. + --> + + <Page.Resources> + <DataTemplate x:Key="NavMenuItemTemplate" x:DataType="local:NavMenuItem" > + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="48" /> + <ColumnDefinition /> + </Grid.ColumnDefinitions> + <Rectangle x:Name="SelectedPipe" + Width="6" + Height="24" + Margin="-2,0,0,0" + Fill="DodgerBlue" + Visibility="{x:Bind SelectedVis, Mode=TwoWay}" + VerticalAlignment="Center" + HorizontalAlignment="Left"/> + <!-- Showing a ToolTip and the Label is redundant. We put the ToolTip on the icon. + It appears when the user hovers over the icon, but not the label which provides + value when the SplitView is 'Compact' while reducing the likelihood of showing + redundant information when the label is shown.--> + <FontIcon x:Name="Glyph" FontSize="16" Glyph="{x:Bind SymbolAsChar}" VerticalAlignment="Center" HorizontalAlignment="Center" ToolTipService.ToolTip="{x:Bind Label}"/> + <TextBlock x:Name="Text" Grid.Column="1" Text="{x:Bind Label}" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" VerticalAlignment="Center"/> + </Grid> + </DataTemplate> + + </Page.Resources> + + <Grid x:Name="LayoutRoot"> + + <Grid.ColumnDefinitions> + <ColumnDefinition Width="48"/> + <ColumnDefinition/> + </Grid.ColumnDefinitions> + + <Grid.RowDefinitions> + <RowDefinition Height="48"/> + <RowDefinition/> + </Grid.RowDefinitions> + + <!-- Declared first for screen reader navigation order, ZIndex specified to have it rendered above everything else. --> + <ToggleButton x:Name="TogglePaneButton" + Canvas.ZIndex="100" + TabIndex="1" + Style="{StaticResource SplitViewTogglePaneButtonStyle}" + IsChecked="{Binding IsPaneOpen, ElementName=RootSplitView, Mode=TwoWay}" + ToolTipService.ToolTip="Navigation"/> + + <Grid Grid.Column="1" Grid.Row="0" Background="White"> + + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="200"/> + </Grid.ColumnDefinitions> + + <Image Grid.Column="0" Source="/Assets/Images/fvacanceslogo.png" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="200,5,0,5" Height="40" /> + <StackPanel x:Name="StackPanel1" Grid.Column="1" Orientation="Horizontal"> + <AppBarButton Icon="AddFriend" Label="Sign up" Style="{StaticResource SignButtonStyle}" Width="Auto" Click="GoToCreateUserView"/> + <AppBarButton Icon="Contact" Label="Sign in" Style="{StaticResource SignButtonStyle}" Width="Auto" Click="GoToLoginView"/> + </StackPanel> + <StackPanel x:Name="StackPanel2" Grid.Column="1" Orientation="Horizontal" Visibility="Collapsed"> + <StackPanel.DataContext> + <viewModel:LoginUserViewModel/> + </StackPanel.DataContext> + <AppBarButton Icon="Contact" Label="My account" Style="{StaticResource SignButtonStyle}" Width="Auto" Click="GoToUserView"/> + <AppBarButton Icon="Sync" Label="Logout" Style="{StaticResource SignButtonStyle}" Width="Auto" Command="{Binding LogOutCommand}"/> + </StackPanel> + </Grid> + + <!-- Top-level navigation menu + app content --> + <SplitView x:Name="RootSplitView" + Grid.Column="0" + Grid.ColumnSpan="2" + Grid.Row="1" + DisplayMode="CompactInline" + OpenPaneLength="200" + PaneBackground="{ThemeResource ApplicationPageBackgroundThemeBrush}" + IsTabStop="False"> + + <SplitView.Pane> + <Grid x:Name="PaneContentGrid"> + + + <!-- A custom ListView to display the items in the pane. The automation Name is set in the ContainerContentChanging event. --> + <controls:NavMenuListView x:Name="NavMenuList" + TabIndex="3" + ItemContainerStyle="{StaticResource NavMenuItemContainerStyle}" + ItemTemplate="{StaticResource NavMenuItemTemplate}" + ItemInvoked="NavMenuList_ItemInvoked"/> + <controls:NavMenuListView x:Name="NavMenuList2" + TabIndex="3" + Margin="0" + ItemContainerStyle="{StaticResource NavMenuItemContainerStyle}" + ItemTemplate="{StaticResource NavMenuItemTemplate}" + ItemInvoked="NavMenuList_ItemInvoked" + VerticalAlignment="Bottom"/> + + </Grid> + </SplitView.Pane> + + <SplitView.Content> + <!-- OnNavigatingToPage we synchronize the selected item in the nav menu with the current page.--> + <Frame x:Name="Frame" + Margin="0,0,0,0" + Navigating="OnNavigatingToPage"> + <Frame.ContentTransitions> + <TransitionCollection> + <NavigationThemeTransition> + <NavigationThemeTransition.DefaultNavigationTransitionInfo> + <EntranceNavigationTransitionInfo/> + </NavigationThemeTransition.DefaultNavigationTransitionInfo> + </NavigationThemeTransition> + </TransitionCollection> + </Frame.ContentTransitions> + </Frame> + </SplitView.Content> + </SplitView> + </Grid> +</Page> 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 +{ + /// <summary> + /// The "chrome" layer of the app that provides top-level navigation with + /// proper keyboarding navigation. + /// </summary> + public sealed partial class AppShell : Page + { + // Declare the top level nav items + private List<NavMenuItem> navMenuItems = new List<NavMenuItem>( + new[] + { + new NavMenuItem() + { + Symbol = Symbol.Home, + Label = "Home", + DestPage = typeof(LoginPage), + IsSelected = true + } + }); + + public static AppShell Current = null; + + /// <summary> + /// 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. + /// </summary> + public AppShell() + { + InitializeComponent(); + + List<NavMenuItem> topNavMenuItems = navMenuItems.GetRange(0, 3); + List<NavMenuItem> bottomNavMenuItems = navMenuItems.GetRange(3, 2); + + NavMenuList.ItemsSource = topNavMenuItems; + NavMenuList2.ItemsSource = bottomNavMenuItems; + } + + public Frame AppFrame { get { return Frame; } } + + #region Navigation + + /// <summary> + /// Navigate to the Page for the selected <paramref name="listViewItem"/>. + /// </summary> + /// <param name="sender"></param> + /// <param name="listViewItem"></param> + 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); + } + } + } + + /// <summary> + /// Ensures the nav menu reflects reality when navigation is triggered outside of + /// the nav menu buttons. + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + 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 + + /// <summary> + /// Public method to allow pages to open SplitView's pane. + /// Used for custom app shortcuts like navigating left from page's left-most item + /// </summary> + 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 +{ + /// <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 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 +{ + /// <summary> + /// Data to represent an item in the nav menu. + /// </summary> + 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 Binary files differindex fdfb54c..f653838 100644 --- a/HousingDatabase.ldf +++ b/HousingDatabase.ldf diff --git a/HousingDatabase.mdf b/HousingDatabase.mdf Binary files differindex 210fa00..14ef64e 100644 --- a/HousingDatabase.mdf +++ b/HousingDatabase.mdf |