diff --git a/src/Artemis.UI/AppBootstrapper.cs b/src/Artemis.UI/AppBootstrapper.cs index f1d87304a..ed60cb899 100644 --- a/src/Artemis.UI/AppBootstrapper.cs +++ b/src/Artemis.UI/AppBootstrapper.cs @@ -23,17 +23,19 @@ namespace Artemis.UI this.WhenAnyValue(x => x.Router.CurrentViewModel) .Subscribe(o => o.Subscribe(vm => { ViewTitle = vm != null ? vm.UrlPathSegment : ""; })); + // Setup the sidebar that lives throughout the app + SidebarViewModel = Kernel.Get(); // Navigate to the opening page of the application Router.Navigate.Execute(Kernel.Get()); } public IKernel Kernel { get; set; } + public ISidebarViewModel SidebarViewModel { get; } + public RoutingState Router { get; } [Reactive] public string ViewTitle { get; set; } - public RoutingState Router { get; } - private void SetupNinject(IKernel kernel) { // Bind the main screen to IScreen diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 7ea1667d1..d4a87f63c 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -101,10 +101,15 @@ + + MainView.xaml + + SidebarView.xaml + MSBuild:Compile Designer @@ -121,6 +126,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + @@ -163,9 +172,7 @@ - - - + diff --git a/src/Artemis.UI/MainWindow.xaml b/src/Artemis.UI/MainWindow.xaml index 64346ce33..a80ee238e 100644 --- a/src/Artemis.UI/MainWindow.xaml +++ b/src/Artemis.UI/MainWindow.xaml @@ -73,13 +73,7 @@ DockPanel.Dock="Top" HorizontalAlignment="Right" Margin="16" IsChecked="{Binding ElementName=MenuToggleButton, Path=IsChecked, Mode=TwoWay}" /> - - - - - - - + diff --git a/src/Artemis.UI/Ninject/ViewsModule.cs b/src/Artemis.UI/Ninject/ViewsModule.cs index e2390162c..59af3febf 100644 --- a/src/Artemis.UI/Ninject/ViewsModule.cs +++ b/src/Artemis.UI/Ninject/ViewsModule.cs @@ -8,6 +8,7 @@ namespace Artemis.UI.Ninject public override void Load() { Bind().To(); + Bind().To().InSingletonScope(); } } } \ No newline at end of file diff --git a/src/Artemis.UI/ViewModels/Interfaces/IArtemisViewModel.cs b/src/Artemis.UI/ViewModels/Interfaces/IArtemisViewModel.cs new file mode 100644 index 000000000..532031971 --- /dev/null +++ b/src/Artemis.UI/ViewModels/Interfaces/IArtemisViewModel.cs @@ -0,0 +1,10 @@ +using ReactiveUI; + +namespace Artemis.UI.ViewModels.Interfaces +{ + public interface IArtemisViewModel : IRoutableViewModel + { + string Title { get; } + string Icon { get; } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/ViewModels/MainViewModel.cs b/src/Artemis.UI/ViewModels/MainViewModel.cs index 497540942..9e093f676 100644 --- a/src/Artemis.UI/ViewModels/MainViewModel.cs +++ b/src/Artemis.UI/ViewModels/MainViewModel.cs @@ -1,19 +1,26 @@ using System.Diagnostics; using System.Threading.Tasks; +using Artemis.UI.ViewModels.Interfaces; using ReactiveUI; namespace Artemis.UI.ViewModels { public class MainViewModel : ReactiveObject, IMainViewModel { - public MainViewModel(IScreen screen) + public MainViewModel(IScreen screen, ISidebarViewModel sidebarViewModel) { HostScreen = screen; OpenUrl = ReactiveCommand.CreateFromTask(OpenUrlAsync); + + // Add this view as a menu item + sidebarViewModel.MenuItems.Add(this); } public IScreen HostScreen { get; } - public string UrlPathSegment => "Home"; + public string UrlPathSegment => Title.ToLower(); + public string Title => "Home"; + public string Icon => "Home"; + public ReactiveCommand OpenUrl { get; } private async Task OpenUrlAsync(string url) @@ -22,7 +29,7 @@ namespace Artemis.UI.ViewModels } } - public interface IMainViewModel : IRoutableViewModel + public interface IMainViewModel : IArtemisViewModel { ReactiveCommand OpenUrl { get; } } diff --git a/src/Artemis.UI/ViewModels/SidebarViewModel.cs b/src/Artemis.UI/ViewModels/SidebarViewModel.cs new file mode 100644 index 000000000..58aa6cbb7 --- /dev/null +++ b/src/Artemis.UI/ViewModels/SidebarViewModel.cs @@ -0,0 +1,23 @@ +using System.Collections.ObjectModel; +using Artemis.UI.ViewModels.Interfaces; +using ReactiveUI; + +namespace Artemis.UI.ViewModels +{ + public class SidebarViewModel : ReactiveObject, ISidebarViewModel + { + public SidebarViewModel(IScreen screen) + { + HostScreen = screen; + MenuItems = new ObservableCollection(); + } + + public IScreen HostScreen { get; } + public ObservableCollection MenuItems { get; set; } + } + + public interface ISidebarViewModel + { + ObservableCollection MenuItems { get; set; } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Views/SidebarView.xaml b/src/Artemis.UI/Views/SidebarView.xaml new file mode 100644 index 000000000..807763a9d --- /dev/null +++ b/src/Artemis.UI/Views/SidebarView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/src/Artemis.UI/Views/SidebarView.xaml.cs b/src/Artemis.UI/Views/SidebarView.xaml.cs new file mode 100644 index 000000000..1a08325fc --- /dev/null +++ b/src/Artemis.UI/Views/SidebarView.xaml.cs @@ -0,0 +1,30 @@ +using System.Windows; +using System.Windows.Controls; +using Artemis.UI.ViewModels; +using ReactiveUI; + +namespace Artemis.UI.Views +{ + /// + /// Interaction logic for SidebarView.xaml + /// + public partial class SidebarView : UserControl, IViewFor + { + public static readonly DependencyProperty ViewModelProperty = + DependencyProperty.Register("ViewModel", typeof(ISidebarViewModel), typeof(SidebarView), new PropertyMetadata(null)); + + public SidebarView() + { + InitializeComponent(); + this.WhenAnyValue(x => x.ViewModel).BindTo(this, x => x.DataContext); + } + + object IViewFor.ViewModel + { + get => ViewModel; + set => ViewModel = (ISidebarViewModel)value; + } + + public ISidebarViewModel ViewModel { get; set; } + } +} \ No newline at end of file