First pass at navigation with MasterDetail
This commit is contained in:
@ -1,5 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Aurora.App">
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Application xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:converters="clr-namespace:Aurora.Frontend.Converters"
|
||||
x:Class="Aurora.App">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<!-- GENERAL COLORS -->
|
||||
<Color x:Key="WhiteColor">#FFFFFF</Color>
|
||||
<Color x:Key="BlackColor">#000000</Color>
|
||||
|
||||
<!-- THEME COLORS -->
|
||||
<Color x:Key="AccentColor">#F5C210</Color>
|
||||
<Color x:Key="ToolbarColor">#151C25</Color>
|
||||
<Color x:Key="BackgroundColor">#1E2634</Color>
|
||||
<Color x:Key="DarkBackgroundColor">#151C25</Color>
|
||||
<Color x:Key="MenuBackgroundColor">#44545C</Color>
|
||||
|
||||
<!-- CONVERTERS -->
|
||||
<converters:InverseBoolConverter x:Key="InverseBoolConverter" />
|
||||
<converters:ToUpperConverter x:Key="ToUpperConverter" />
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Aurora.Frontend.Views.Main;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
@ -10,7 +11,7 @@ namespace Aurora
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
MainPage = new MainPage();
|
||||
MainPage = new MainView();
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
|
@ -14,4 +14,13 @@
|
||||
<PackageReference Include="Xamarin.Forms" Version="3.6.0.264807" />
|
||||
<PackageReference Include="Xamarin.Essentials" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Frontend\" />
|
||||
<Folder Include="Backend\" />
|
||||
<Folder Include="Frontend\Components\" />
|
||||
<Folder Include="Frontend\Views\" />
|
||||
<Folder Include="Frontend\Views\Home\" />
|
||||
<Folder Include="Frontend\Views\MainView\" />
|
||||
<Folder Include="Frontend\Behaviors\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
42
Aurora/Frontend/Behaviors/BehaviorBase.cs
Normal file
42
Aurora/Frontend/Behaviors/BehaviorBase.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora.Frontend.Behaviors
|
||||
{
|
||||
public class BehaviorBase<T> : Behavior<T> where T : BindableObject
|
||||
{
|
||||
public T AssociatedObject { get; private set; }
|
||||
|
||||
protected override void OnAttachedTo(T bindable)
|
||||
{
|
||||
base.OnAttachedTo(bindable);
|
||||
AssociatedObject = bindable;
|
||||
|
||||
if (bindable.BindingContext != null)
|
||||
{
|
||||
BindingContext = bindable.BindingContext;
|
||||
}
|
||||
|
||||
bindable.BindingContextChanged += OnBindingContextChanged;
|
||||
}
|
||||
|
||||
protected override void OnDetachingFrom(T bindable)
|
||||
{
|
||||
base.OnDetachingFrom(bindable);
|
||||
bindable.BindingContextChanged -= OnBindingContextChanged;
|
||||
AssociatedObject = null;
|
||||
}
|
||||
|
||||
void OnBindingContextChanged(object sender, EventArgs e)
|
||||
{
|
||||
OnBindingContextChanged();
|
||||
}
|
||||
|
||||
protected override void OnBindingContextChanged()
|
||||
{
|
||||
base.OnBindingContextChanged();
|
||||
BindingContext = AssociatedObject.BindingContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
132
Aurora/Frontend/Behaviors/EventToCommandBehavior.cs
Normal file
132
Aurora/Frontend/Behaviors/EventToCommandBehavior.cs
Normal file
@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Windows.Input;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora.Frontend.Behaviors
|
||||
{
|
||||
public class EventToCommandBehavior : BehaviorBase<View>
|
||||
{
|
||||
Delegate eventHandler;
|
||||
|
||||
public static readonly BindableProperty EventNameProperty = BindableProperty.Create("EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
|
||||
public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(EventToCommandBehavior), null);
|
||||
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(EventToCommandBehavior), null);
|
||||
public static readonly BindableProperty InputConverterProperty = BindableProperty.Create("Converter", typeof(IValueConverter), typeof(EventToCommandBehavior), null);
|
||||
|
||||
public string EventName
|
||||
{
|
||||
get { return (string)GetValue(EventNameProperty); }
|
||||
set { SetValue(EventNameProperty, value); }
|
||||
}
|
||||
|
||||
public ICommand Command
|
||||
{
|
||||
get { return (ICommand)GetValue(CommandProperty); }
|
||||
set { SetValue(CommandProperty, value); }
|
||||
}
|
||||
|
||||
public object CommandParameter
|
||||
{
|
||||
get { return GetValue(CommandParameterProperty); }
|
||||
set { SetValue(CommandParameterProperty, value); }
|
||||
}
|
||||
|
||||
public IValueConverter Converter
|
||||
{
|
||||
get { return (IValueConverter)GetValue(InputConverterProperty); }
|
||||
set { SetValue(InputConverterProperty, value); }
|
||||
}
|
||||
|
||||
protected override void OnAttachedTo(View bindable)
|
||||
{
|
||||
base.OnAttachedTo(bindable);
|
||||
RegisterEvent(EventName);
|
||||
}
|
||||
|
||||
protected override void OnDetachingFrom(View bindable)
|
||||
{
|
||||
DeregisterEvent(EventName);
|
||||
base.OnDetachingFrom(bindable);
|
||||
}
|
||||
|
||||
void RegisterEvent(string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
|
||||
if (eventInfo == null)
|
||||
{
|
||||
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't register the '{0}' event.", EventName));
|
||||
}
|
||||
MethodInfo methodInfo = typeof(EventToCommandBehavior).GetTypeInfo().GetDeclaredMethod("OnEvent");
|
||||
eventHandler = methodInfo.CreateDelegate(eventInfo.EventHandlerType, this);
|
||||
eventInfo.AddEventHandler(AssociatedObject, eventHandler);
|
||||
}
|
||||
|
||||
void DeregisterEvent(string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
|
||||
if (eventInfo == null)
|
||||
{
|
||||
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't de-register the '{0}' event.", EventName));
|
||||
}
|
||||
eventInfo.RemoveEventHandler(AssociatedObject, eventHandler);
|
||||
eventHandler = null;
|
||||
}
|
||||
|
||||
void OnEvent(object sender, object eventArgs)
|
||||
{
|
||||
if (Command == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
object resolvedParameter;
|
||||
if (CommandParameter != null)
|
||||
{
|
||||
resolvedParameter = CommandParameter;
|
||||
}
|
||||
else if (Converter != null)
|
||||
{
|
||||
resolvedParameter = Converter.Convert(eventArgs, typeof(object), null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
resolvedParameter = eventArgs;
|
||||
}
|
||||
|
||||
if (Command.CanExecute(resolvedParameter))
|
||||
{
|
||||
Command.Execute(resolvedParameter);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
var behavior = (EventToCommandBehavior)bindable;
|
||||
if (behavior.AssociatedObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string oldEventName = (string)oldValue;
|
||||
string newEventName = (string)newValue;
|
||||
|
||||
behavior.DeregisterEvent(oldEventName);
|
||||
behavior.RegisterEvent(newEventName);
|
||||
}
|
||||
}
|
||||
}
|
38
Aurora/Frontend/Components/ContentPresenter.cs
Normal file
38
Aurora/Frontend/Components/ContentPresenter.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora.Frontend.Components
|
||||
{
|
||||
public class ContentPresenter : ContentView
|
||||
{
|
||||
public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(ContentPresenter), null, propertyChanged: OnItemTemplateChanged);
|
||||
|
||||
private static void OnItemTemplateChanged(BindableObject bindable, object oldvalue, object newvalue)
|
||||
{
|
||||
var cp = (ContentPresenter)bindable;
|
||||
|
||||
var template = cp.ItemTemplate;
|
||||
if (template != null)
|
||||
{
|
||||
var content = (View)template.CreateContent();
|
||||
cp.Content = content;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp.Content = null;
|
||||
}
|
||||
}
|
||||
|
||||
public DataTemplate ItemTemplate
|
||||
{
|
||||
get
|
||||
{
|
||||
return (DataTemplate)GetValue(ItemTemplateProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ItemTemplateProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
168
Aurora/Frontend/Components/HorizontalList/HorizontalList.cs
Executable file
168
Aurora/Frontend/Components/HorizontalList/HorizontalList.cs
Executable file
@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Input;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Movies.Controls
|
||||
{
|
||||
public class HorizontalList : Grid
|
||||
{
|
||||
private ICommand _innerSelectedCommand;
|
||||
private readonly ScrollView _scrollView;
|
||||
private readonly StackLayout _itemsStackLayout;
|
||||
|
||||
public event EventHandler SelectedItemChanged;
|
||||
|
||||
public StackOrientation ListOrientation { get; set; }
|
||||
|
||||
public double Spacing { get; set; }
|
||||
|
||||
public static readonly BindableProperty SelectedCommandProperty =
|
||||
BindableProperty.Create("SelectedCommand", typeof(ICommand), typeof(HorizontalList), null);
|
||||
|
||||
public static readonly BindableProperty ItemsSourceProperty =
|
||||
BindableProperty.Create("ItemsSource", typeof(IEnumerable), typeof(HorizontalList), default(IEnumerable<object>), BindingMode.TwoWay, propertyChanged: ItemsSourceChanged);
|
||||
|
||||
public static readonly BindableProperty SelectedItemProperty =
|
||||
BindableProperty.Create("SelectedItem", typeof(object), typeof(HorizontalList), null, BindingMode.TwoWay, propertyChanged: OnSelectedItemChanged);
|
||||
|
||||
public static readonly BindableProperty ItemTemplateProperty =
|
||||
BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(HorizontalList), default(DataTemplate));
|
||||
|
||||
public ICommand SelectedCommand
|
||||
{
|
||||
get { return (ICommand)GetValue(SelectedCommandProperty); }
|
||||
set { SetValue(SelectedCommandProperty, value); }
|
||||
}
|
||||
|
||||
public IEnumerable ItemsSource
|
||||
{
|
||||
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
|
||||
set { SetValue(ItemsSourceProperty, value); }
|
||||
}
|
||||
|
||||
public object SelectedItem
|
||||
{
|
||||
get { return (object)GetValue(SelectedItemProperty); }
|
||||
set { SetValue(SelectedItemProperty, value); }
|
||||
}
|
||||
|
||||
public DataTemplate ItemTemplate
|
||||
{
|
||||
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
|
||||
set { SetValue(ItemTemplateProperty, value); }
|
||||
}
|
||||
|
||||
private static void ItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
var itemsLayout = (HorizontalList)bindable;
|
||||
itemsLayout.SetItems();
|
||||
}
|
||||
|
||||
public HorizontalList()
|
||||
{
|
||||
BackgroundColor = Color.FromHex("#1E2634");
|
||||
Spacing = 6;
|
||||
_scrollView = new ScrollView();
|
||||
_itemsStackLayout = new StackLayout
|
||||
{
|
||||
BackgroundColor = BackgroundColor,
|
||||
Padding = Padding,
|
||||
Spacing = Spacing,
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand
|
||||
};
|
||||
|
||||
_scrollView.BackgroundColor = BackgroundColor;
|
||||
_scrollView.Content = _itemsStackLayout;
|
||||
Children.Add(_scrollView);
|
||||
}
|
||||
|
||||
protected virtual void SetItems()
|
||||
{
|
||||
_itemsStackLayout.Children.Clear();
|
||||
_itemsStackLayout.Spacing = Spacing;
|
||||
|
||||
_innerSelectedCommand = new Command<View>(view =>
|
||||
{
|
||||
SelectedItem = view.BindingContext;
|
||||
SelectedItem = null; // Allowing item second time selection
|
||||
});
|
||||
|
||||
_itemsStackLayout.Orientation = ListOrientation;
|
||||
_scrollView.Orientation = ListOrientation == StackOrientation.Horizontal
|
||||
? ScrollOrientation.Horizontal
|
||||
: ScrollOrientation.Vertical;
|
||||
|
||||
if (ItemsSource == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var item in ItemsSource)
|
||||
{
|
||||
_itemsStackLayout.Children.Add(GetItemView(item));
|
||||
}
|
||||
|
||||
_itemsStackLayout.BackgroundColor = BackgroundColor;
|
||||
SelectedItem = null;
|
||||
}
|
||||
|
||||
protected virtual View GetItemView(object item)
|
||||
{
|
||||
var content = ItemTemplate.CreateContent();
|
||||
var view = content as View;
|
||||
|
||||
if (view == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
view.BindingContext = item;
|
||||
|
||||
var gesture = new TapGestureRecognizer
|
||||
{
|
||||
Command = _innerSelectedCommand,
|
||||
CommandParameter = view
|
||||
};
|
||||
|
||||
AddGesture(view, gesture);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void AddGesture(View view, TapGestureRecognizer gesture)
|
||||
{
|
||||
view.GestureRecognizers.Add(gesture);
|
||||
|
||||
var layout = view as Layout<View>;
|
||||
|
||||
if (layout == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var child in layout.Children)
|
||||
{
|
||||
AddGesture(child, gesture);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSelectedItemChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
var itemsView = (HorizontalList)bindable;
|
||||
|
||||
if (newValue == oldValue && newValue != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
itemsView.SelectedItemChanged?.Invoke(itemsView, EventArgs.Empty);
|
||||
|
||||
if (itemsView.SelectedCommand?.CanExecute(newValue) ?? false)
|
||||
{
|
||||
itemsView.SelectedCommand?.Execute(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
Aurora/Frontend/Converters/InverseBoolConverter.cs
Executable file
24
Aurora/Frontend/Converters/InverseBoolConverter.cs
Executable file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora.Frontend.Converters
|
||||
{
|
||||
public class InverseBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is bool))
|
||||
{
|
||||
throw new InvalidOperationException("The target must be a boolean");
|
||||
}
|
||||
|
||||
return !(bool)value;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
19
Aurora/Frontend/Converters/ToUpperConverter.cs
Executable file
19
Aurora/Frontend/Converters/ToUpperConverter.cs
Executable file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora.Frontend.Converters
|
||||
{
|
||||
public class ToUpperConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value.ToString().ToUpper();
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
9
Aurora/Frontend/Views/MainView/MainContentPage.xaml
Normal file
9
Aurora/Frontend/Views/MainView/MainContentPage.xaml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Aurora.Frontend.Views.Main.MainContentPage"
|
||||
Title="Detail">
|
||||
<StackLayout>
|
||||
<Label Text="This is a detail page. To get the 'triple' line icon on each platform add a icon to each platform and update the 'Master' page with an Icon that references it." />
|
||||
</StackLayout>
|
||||
</ContentPage>
|
14
Aurora/Frontend/Views/MainView/MainContentPage.xaml.cs
Normal file
14
Aurora/Frontend/Views/MainView/MainContentPage.xaml.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace Aurora.Frontend.Views.Main
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class MainContentPage : ContentPage
|
||||
{
|
||||
public MainContentPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
38
Aurora/Frontend/Views/MainView/MainView.xaml
Normal file
38
Aurora/Frontend/Views/MainView/MainView.xaml
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:views="clr-namespace:Aurora.Frontend.Views.Main"
|
||||
x:Class="Aurora.Frontend.Views.Main.MainView">
|
||||
<ContentPage.Content>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<views:NavigationMenu Grid.Column="0"/>
|
||||
|
||||
</Grid>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>-->
|
||||
|
||||
<MasterDetailPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:views="clr-namespace:Aurora.Frontend.Views.Main"
|
||||
x:Class="Aurora.Frontend.Views.Main.MainView"
|
||||
MasterBehavior="Split">
|
||||
|
||||
<MasterDetailPage.Master>
|
||||
<views:NavigationMenu x:Name="MasterPage"/>
|
||||
</MasterDetailPage.Master>
|
||||
|
||||
<MasterDetailPage.Detail>
|
||||
<NavigationPage>
|
||||
<x:Arguments>
|
||||
<views:MainContentPage />
|
||||
</x:Arguments>
|
||||
</NavigationPage>
|
||||
</MasterDetailPage.Detail>
|
||||
|
||||
</MasterDetailPage>
|
33
Aurora/Frontend/Views/MainView/MainView.xaml.cs
Normal file
33
Aurora/Frontend/Views/MainView/MainView.xaml.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace Aurora.Frontend.Views.Main
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class MainView : MasterDetailPage
|
||||
{
|
||||
public MainView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
MasterPage.ListView.ItemSelected += ListView_ItemSelected;
|
||||
}
|
||||
|
||||
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
var item = e.SelectedItem as NavigationItem;
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
var page = (Page)Activator.CreateInstance(item.TargetType);
|
||||
page.Title = item.Title;
|
||||
|
||||
Detail = new NavigationPage(page);
|
||||
|
||||
MasterPage.ListView.SelectedItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
20
Aurora/Frontend/Views/MainView/NavigationItem.cs
Normal file
20
Aurora/Frontend/Views/MainView/NavigationItem.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Aurora.Frontend.Views.Main
|
||||
{
|
||||
public class NavigationItem
|
||||
{
|
||||
public NavigationItem()
|
||||
{
|
||||
TargetType = typeof(MainContentPage);
|
||||
}
|
||||
public int Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
public Type TargetType { get; set; }
|
||||
}
|
||||
}
|
41
Aurora/Frontend/Views/MainView/NavigationMenu.xaml
Normal file
41
Aurora/Frontend/Views/MainView/NavigationMenu.xaml
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Aurora.Frontend.Views.Main.NavigationMenu"
|
||||
Title="asdf">
|
||||
<StackLayout>
|
||||
<ListView x:Name="MenuItemsListView"
|
||||
SeparatorVisibility="None"
|
||||
HasUnevenRows="true"
|
||||
BackgroundColor="{StaticResource MenuBackgroundColor}"
|
||||
CachingStrategy="RecycleElement"
|
||||
ItemsSource="{Binding MenuItems}">
|
||||
<ListView.Header>
|
||||
<Grid BackgroundColor="#03A9F4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="80" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="10" />
|
||||
</Grid.RowDefinitions>
|
||||
<Label Grid.Column="1" Grid.Row="2" Text="AppName" Style="{DynamicResource SubtitleStyle}" />
|
||||
</Grid>
|
||||
</ListView.Header>
|
||||
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ViewCell>
|
||||
<StackLayout Padding="15,10" HorizontalOptions="FillAndExpand">
|
||||
<Label VerticalOptions="FillAndExpand" VerticalTextAlignment="Center" Text="{Binding Title}" FontSize="24" />
|
||||
</StackLayout>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
56
Aurora/Frontend/Views/MainView/NavigationMenu.xaml.cs
Normal file
56
Aurora/Frontend/Views/MainView/NavigationMenu.xaml.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace Aurora.Frontend.Views.Main
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class NavigationMenu : ContentPage
|
||||
{
|
||||
public ListView ListView;
|
||||
|
||||
public NavigationMenu()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = new MainViewMasterViewModel();
|
||||
ListView = MenuItemsListView;
|
||||
}
|
||||
|
||||
class MainViewMasterViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public ObservableCollection<NavigationItem> MenuItems { get; set; }
|
||||
|
||||
public MainViewMasterViewModel()
|
||||
{
|
||||
MenuItems = new ObservableCollection<NavigationItem>(new[]
|
||||
{
|
||||
new NavigationItem { Id = 0, Title = "Page 1" },
|
||||
new NavigationItem { Id = 1, Title = "Page 2" },
|
||||
new NavigationItem { Id = 2, Title = "Page 3" },
|
||||
new NavigationItem { Id = 3, Title = "Page 4" },
|
||||
new NavigationItem { Id = 4, Title = "Page 5" },
|
||||
});
|
||||
}
|
||||
|
||||
#region INotifyPropertyChanged Implementation
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
void OnPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
if (PropertyChanged == null)
|
||||
return;
|
||||
|
||||
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Aurora" x:Class="Aurora.MainPage">
|
||||
<StackLayout>
|
||||
<!-- Place new controls here -->
|
||||
<Label Text="Welcome to Xamarin.Forms!" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
|
||||
</StackLayout>
|
||||
</ContentPage>
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora
|
||||
{
|
||||
// Learn more about making custom code visible in the Xamarin.Forms previewer
|
||||
// by visiting https://aka.ms/xamarinforms-previewer
|
||||
[DesignTimeVisible(true)]
|
||||
public partial class MainPage : ContentPage
|
||||
{
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user