diff --git a/Hyperbar.UI.Windows/IViewModelContentBinder.cs b/Hyperbar.UI.Windows/IViewModelContentBinder.cs new file mode 100644 index 0000000..378ff80 --- /dev/null +++ b/Hyperbar.UI.Windows/IViewModelContentBinder.cs @@ -0,0 +1,9 @@ +using Microsoft.UI.Xaml; + +namespace Hyperbar.UI.Windows; + +public interface IViewModelContentBinder +{ + void Bind(FrameworkElement view, + object context); +} diff --git a/Hyperbar.UI.Windows/IViewModelTemplate.cs b/Hyperbar.UI.Windows/IViewModelTemplate.cs deleted file mode 100644 index fa34338..0000000 --- a/Hyperbar.UI.Windows/IViewModelTemplate.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Hyperbar.UI.Windows; - -public interface IViewModelTemplate -{ - -} diff --git a/Hyperbar.UI.Windows/IViewModelTemplateSelector.cs b/Hyperbar.UI.Windows/IViewModelTemplateSelector.cs new file mode 100644 index 0000000..91392b7 --- /dev/null +++ b/Hyperbar.UI.Windows/IViewModelTemplateSelector.cs @@ -0,0 +1,6 @@ +namespace Hyperbar.UI.Windows; + +public interface IViewModelTemplateSelector +{ + +} diff --git a/Hyperbar.UI.Windows/NavigateAction.cs b/Hyperbar.UI.Windows/NavigateAction.cs index 78e839e..1d2f2dc 100644 --- a/Hyperbar.UI.Windows/NavigateAction.cs +++ b/Hyperbar.UI.Windows/NavigateAction.cs @@ -7,15 +7,25 @@ public sealed class NavigateAction : DependencyObject, IAction { - public static readonly DependencyProperty PathProperty = - DependencyProperty.Register(nameof(Path), + public static readonly DependencyProperty NameProperty = + DependencyProperty.Register(nameof(Name), typeof(string), typeof(NavigateAction), new PropertyMetadata(null)); - public string Path + public static readonly DependencyProperty TargetNameProperty = + DependencyProperty.Register(nameof(Name), + typeof(string), typeof(NavigateAction), + new PropertyMetadata(null)); + public string Name { - get => (string)GetValue(PathProperty); - set => SetValue(PathProperty, value); + get => (string)GetValue(NameProperty); + set => SetValue(NameProperty, value); + } + + public string TargetName + { + get => (string)GetValue(TargetNameProperty); + set => SetValue(TargetNameProperty, value); } public object Execute(object sender, object parameter) @@ -24,7 +34,7 @@ public sealed class NavigateAction : { if (frameworkElement.DataContext is IObservableViewModel observableViewModel) { - observableViewModel.Publisher.PublishAsync(new Navigate(Path)) + observableViewModel.Publisher.PublishAsync(new Navigate(Name, TargetName ?? null)) .GetAwaiter().GetResult(); } } diff --git a/Hyperbar.UI.Windows/ViewModelContentBinder.cs b/Hyperbar.UI.Windows/ViewModelContentBinder.cs new file mode 100644 index 0000000..eeec6c5 --- /dev/null +++ b/Hyperbar.UI.Windows/ViewModelContentBinder.cs @@ -0,0 +1,31 @@ +using Microsoft.UI.Xaml; +using System.Reflection; + +namespace Hyperbar.UI.Windows; + +public class ViewModelContentBinder(NavigationTargetCollection contents) : + IViewModelContentBinder +{ + public void Bind(FrameworkElement view, + object context) + { + if (context.GetType().GetCustomAttributes() + is IEnumerable attributes) + { + foreach (NavigationTargetAttribute attribute in attributes) + { + if (view.FindName(attribute.Name) is FrameworkElement content) + { + contents.Add(attribute.Name, content); + void HandleUnloaded(object sender, RoutedEventArgs args) + { + view.Unloaded -= HandleUnloaded; + contents.Remove(attribute.Name); + } + + view.Unloaded += HandleUnloaded; + } + } + } + } +} diff --git a/Hyperbar.UI.Windows/ViewModelTemplate.cs b/Hyperbar.UI.Windows/ViewModelTemplateSelector.cs similarity index 65% rename from Hyperbar.UI.Windows/ViewModelTemplate.cs rename to Hyperbar.UI.Windows/ViewModelTemplateSelector.cs index d63e962..eeb616b 100644 --- a/Hyperbar.UI.Windows/ViewModelTemplate.cs +++ b/Hyperbar.UI.Windows/ViewModelTemplateSelector.cs @@ -4,22 +4,13 @@ using Microsoft.UI.Xaml.Markup; namespace Hyperbar.UI.Windows; -public class ViewModelBinder -{ - public void Bind(object viewModel, - FrameworkElement view) - { - view.DataContext ??= viewModel; - - } -} -public class ViewModelTemplate(IViewModelTemplateDescriptorProvider descriptors) : +public class ViewModelTemplateSelector(IViewModelTemplateProvider descriptors) : DataTemplateSelector, - IViewModelTemplate + IViewModelTemplateSelector { protected override DataTemplate SelectTemplateCore(object item) { - return descriptors.Get(item.GetType().Name) is IViewModelTemplateDescriptor descriptor + return descriptors.Get(item.GetType().Name) is Hyperbar.IViewModelTemplate descriptor ? CreateDataTemplate(descriptor) : new DataTemplate(); } @@ -28,7 +19,7 @@ public class ViewModelTemplate(IViewModelTemplateDescriptorProvider descriptors) DependencyObject container) => SelectTemplateCore(item); - private static DataTemplate CreateDataTemplate(IViewModelTemplateDescriptor descriptor) + private static DataTemplate CreateDataTemplate(Hyperbar.IViewModelTemplate descriptor) { string xamlString = @$" +public class ContentControlHandler(IViewModelContentBinder viewModelContentBinder) : + INavigationHandler { - public Task Handle(Navigate args, - CancellationToken cancellationToken = default) + public Task Handle(Navigate args, + CancellationToken cancellationToken) { + if (args.Target is ContentControl contentControl) + { + contentControl.Content = args.View; + } return Task.CompletedTask; } } -public class WindowHandler : +public class WindowHandler(IViewModelContentBinder viewModelContentBinder) : INavigationHandler { public Task Handle(Navigate args, CancellationToken cancellationToken) { - if (args.View is Window window) + if (args.Target is Window window) { if (window.Content is FrameworkElement content) { @@ -33,8 +37,9 @@ public class WindowHandler : } } - //ViewModelBinder.Bind(args.ViewModel, content); + viewModelContentBinder.Bind(content, window); window.Closed += HandleClosed; + content.DataContext = args.ViewModel; } window.Activate(); diff --git a/Hyperbar.Widget.MediaController.Windows/MediaControllerView.xaml b/Hyperbar.Widget.MediaController.Windows/MediaControllerView.xaml index 31df3e2..f5453b5 100644 --- a/Hyperbar.Widget.MediaController.Windows/MediaControllerView.xaml +++ b/Hyperbar.Widget.MediaController.Windows/MediaControllerView.xaml @@ -2,12 +2,11 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> diff --git a/Hyperbar.Widget.MediaController.Windows/MediaControllerViewModel.cs b/Hyperbar.Widget.MediaController.Windows/MediaControllerViewModel.cs index 4e9c346..695c07c 100644 --- a/Hyperbar.Widget.MediaController.Windows/MediaControllerViewModel.cs +++ b/Hyperbar.Widget.MediaController.Windows/MediaControllerViewModel.cs @@ -7,14 +7,14 @@ namespace Hyperbar.Widget.MediaController.Windows; public class MediaControllerViewModel : ObservableCollectionViewModel { - public MediaControllerViewModel(IViewModelTemplate template, + public MediaControllerViewModel(IViewModelTemplateSelector viewModelTemplateSelector, IServiceProvider serviceProvider, IServiceFactory serviceFactory, IPublisher publisher, ISubscriber subscriber, IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer) { - Template = template; + viewModelTemplateSelector = viewModelTemplateSelector; Add(); @@ -28,5 +28,5 @@ public class MediaControllerViewModel : await publisher.PublishAsync>())); } - public IViewModelTemplate Template { get; } + public IViewModelTemplateSelector ViewModelTemplateSelector { get; } } \ No newline at end of file diff --git a/Hyperbar.Widget.MediaController.Windows/MediaControllerWidgetView.xaml b/Hyperbar.Widget.MediaController.Windows/MediaControllerWidgetView.xaml index 291e3b3..1259aab 100644 --- a/Hyperbar.Widget.MediaController.Windows/MediaControllerWidgetView.xaml +++ b/Hyperbar.Widget.MediaController.Windows/MediaControllerWidgetView.xaml @@ -5,6 +5,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> diff --git a/Hyperbar.Widget.MediaController.Windows/MediaControllerWidgetViewModel.cs b/Hyperbar.Widget.MediaController.Windows/MediaControllerWidgetViewModel.cs index 5962b4d..bdb6ac4 100644 --- a/Hyperbar.Widget.MediaController.Windows/MediaControllerWidgetViewModel.cs +++ b/Hyperbar.Widget.MediaController.Windows/MediaControllerWidgetViewModel.cs @@ -2,7 +2,7 @@ namespace Hyperbar.Widget.MediaController.Windows; -public class MediaControllerWidgetViewModel(IViewModelTemplate template, +public class MediaControllerWidgetViewModel(IViewModelTemplateSelector viewModelTemplateSelector, IServiceProvider serviceProvider, IServiceFactory serviceFactory, IPublisher publisher, @@ -12,5 +12,5 @@ public class MediaControllerWidgetViewModel(IViewModelTemplate template, ObservableCollectionViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, items), IWidgetViewModel { - public IViewModelTemplate Template => template; + public IViewModelTemplateSelector ViewModelTemplateSelector => viewModelTemplateSelector; } \ No newline at end of file diff --git a/Hyperbar.Widget.Windows/IServiceCollectionExtensions.cs b/Hyperbar.Widget.Windows/IServiceCollectionExtensions.cs index d4ece2f..d2dd599 100644 --- a/Hyperbar.Widget.Windows/IServiceCollectionExtensions.cs +++ b/Hyperbar.Widget.Windows/IServiceCollectionExtensions.cs @@ -12,14 +12,14 @@ public static class IServiceCollectionExtensions // We need to feed information to the Widgets about our Windows host, // so the Windows host can make discussions how to display and interact with the widgets. - services.AddTransient>(provider => + services.AddTransient((Func>)(provider => new ProxyServiceCollection(services => { services.AddSingleton(provider.GetRequiredService>()); services.AddSingleton(provider.GetRequiredService()); - services.AddTransient(); - services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddScoped(); services.AddHandler(); @@ -33,7 +33,7 @@ public static class IServiceCollectionExtensions services.AddContentTemplate(); services.AddContentTemplate(); - })); + }))); return services; } diff --git a/Hyperbar.Widget.Windows/WidgetView.xaml b/Hyperbar.Widget.Windows/WidgetView.xaml index f28a283..9cabeb0 100644 --- a/Hyperbar.Widget.Windows/WidgetView.xaml +++ b/Hyperbar.Widget.Windows/WidgetView.xaml @@ -4,10 +4,9 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" - xmlns:interactivity="using:Microsoft.Xaml.Interactivity" - xmlns:ui="using:Hyperbar.UI.Windows"> + xmlns:interactivity="using:Microsoft.Xaml.Interactivity"> - + diff --git a/Hyperbar.Widget/IServiceCollectionExtensions.cs b/Hyperbar.Widget/IServiceCollectionExtensions.cs index 78b5c23..d07bc50 100644 --- a/Hyperbar.Widget/IServiceCollectionExtensions.cs +++ b/Hyperbar.Widget/IServiceCollectionExtensions.cs @@ -33,7 +33,7 @@ public static class IServiceCollectionExtensions services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType); services.TryAddKeyedTransient(key, (provider, key) => provider.GetService()!); - services.AddTransient(provider => new ViewModelTemplateDescriptor { ViewModelType = contentType, TemplateType = templateType, Key = key }); + services.AddTransient(provider => new ViewModelTemplate { ViewModelType = contentType, TemplateType = templateType, Key = key }); return services; } @@ -54,8 +54,8 @@ public static class IServiceCollectionExtensions services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType); services.TryAddKeyedTransient(templateType, key); - services.AddTransient(provider => - new ViewModelTemplateDescriptor { ViewModelType = contentType, + services.AddTransient(provider => + new ViewModelTemplate { ViewModelType = contentType, TemplateType = templateType, Key = key }); return services; diff --git a/Hyperbar.Widget/WidgetBuilder.cs b/Hyperbar.Widget/WidgetBuilder.cs index 3bb314a..736a379 100644 --- a/Hyperbar.Widget/WidgetBuilder.cs +++ b/Hyperbar.Widget/WidgetBuilder.cs @@ -29,8 +29,16 @@ public class WidgetBuilder : services.AddScoped(provider => new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!))); + + services.AddSingleton(); + services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); + services.AddScoped(); + services.AddScoped(); + services.AddHandler(); services.AddValueChangedNotification((config) => (args) => diff --git a/Hyperbar.Windows/App.xaml.cs b/Hyperbar.Windows/App.xaml.cs index 27e8d32..f1e8cf2 100644 --- a/Hyperbar.Windows/App.xaml.cs +++ b/Hyperbar.Windows/App.xaml.cs @@ -21,7 +21,7 @@ public partial class App : base.OnLaunched(args); IHost? host = new HostBuilder() - .UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + .UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Assembly.GetEntryAssembly()?.GetName().Name!), true) .ConfigureAppConfiguration(config => { @@ -36,18 +36,24 @@ public partial class App : services.AddHostedService(); - services.AddSingleton(new Dispatcher(DispatcherQueue.GetForCurrentThread())); + services.AddSingleton((IDispatcher)new Dispatcher(DispatcherQueue.GetForCurrentThread())); - services.AddTransient(); - services.AddTransient(); + services.AddTransient(); + services.AddSingleton(); + services.AddTransient(); + + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddHandler(); - services.AddConfiguration(args => + services.AddConfiguration((AppConfiguration args) => { args.Placement = DesktopApplicationBarPlacemenet.Top; }); services.AddNavigationHandler(); + services.AddNavigationHandler(); services.AddSingleton(); services.AddContentTemplate(); @@ -59,6 +65,7 @@ public partial class App : services.AddContentTemplate(); services.AddContentTemplate(); + services.AddContentTemplate("WidgetSettings"); services.AddTransient(); }) diff --git a/Hyperbar.Windows/ApplicationBarView.xaml b/Hyperbar.Windows/ApplicationBarView.xaml index 71c71f1..4497f68 100644 --- a/Hyperbar.Windows/ApplicationBarView.xaml +++ b/Hyperbar.Windows/ApplicationBarView.xaml @@ -17,7 +17,7 @@ diff --git a/Hyperbar.Windows/ApplicationBarViewModel.cs b/Hyperbar.Windows/ApplicationBarViewModel.cs index da12701..0a92aa2 100644 --- a/Hyperbar.Windows/ApplicationBarViewModel.cs +++ b/Hyperbar.Windows/ApplicationBarViewModel.cs @@ -7,18 +7,18 @@ namespace Hyperbar.Widget; public partial class ApplicationBarViewModel : ObservableCollectionViewModel { - public ApplicationBarViewModel(IViewModelTemplate template, + public ApplicationBarViewModel(IViewModelTemplateSelector viewModelTemplateSelector, IServiceProvider serviceProvider, IServiceFactory serviceFactory, IPublisher publisher, ISubscriber subscriber, IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer) { - Template = template; + ViewModelTemplateSelector = viewModelTemplateSelector; Add(0); Add(1); } - public IViewModelTemplate Template { get; } + public IViewModelTemplateSelector ViewModelTemplateSelector { get; } } \ No newline at end of file diff --git a/Hyperbar.Windows/GeneralSettingsNavigationViewModel.cs b/Hyperbar.Windows/GeneralSettingsNavigationViewModel.cs index aa809d1..f80a57c 100644 --- a/Hyperbar.Windows/GeneralSettingsNavigationViewModel.cs +++ b/Hyperbar.Windows/GeneralSettingsNavigationViewModel.cs @@ -6,6 +6,4 @@ public class GeneralSettingsNavigationViewModel(IServiceProvider serviceProvider ISubscriber subscriber, IDisposer disposer, string text) : - NavigationViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, text) -{ -} \ No newline at end of file + NavigationViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, text); \ No newline at end of file diff --git a/Hyperbar.Windows/Hyperbar.Windows.csproj b/Hyperbar.Windows/Hyperbar.Windows.csproj index 55e427b..eb0a58b 100644 --- a/Hyperbar.Windows/Hyperbar.Windows.csproj +++ b/Hyperbar.Windows/Hyperbar.Windows.csproj @@ -21,6 +21,7 @@ + @@ -57,6 +58,11 @@ + + + MSBuild:Compile + + MSBuild:Compile diff --git a/Hyperbar.Windows/PrimaryView.xaml b/Hyperbar.Windows/PrimaryView.xaml index 28581af..6b68a24 100644 --- a/Hyperbar.Windows/PrimaryView.xaml +++ b/Hyperbar.Windows/PrimaryView.xaml @@ -2,11 +2,10 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> diff --git a/Hyperbar.Windows/PrimaryViewModel.cs b/Hyperbar.Windows/PrimaryViewModel.cs index 9c19576..4cf4207 100644 --- a/Hyperbar.Windows/PrimaryViewModel.cs +++ b/Hyperbar.Windows/PrimaryViewModel.cs @@ -4,7 +4,7 @@ using Hyperbar.UI.Windows; namespace Hyperbar.Widget; [NotificationHandler(nameof(IWidgetHostViewModel))] -public partial class PrimaryViewModel(IViewModelTemplate template, +public partial class PrimaryViewModel(IViewModelTemplateSelector viewModelTemplateSelector, IServiceProvider serviceProvider, IServiceFactory serviceFactory, IPublisher publisher, @@ -17,6 +17,6 @@ public partial class PrimaryViewModel(IViewModelTemplate template, [ObservableProperty] private int index = index; - public IViewModelTemplate Template => template; + public IViewModelTemplateSelector ViewModelTemplateSelector => viewModelTemplateSelector; } \ No newline at end of file diff --git a/Hyperbar.Windows/SecondaryView.xaml b/Hyperbar.Windows/SecondaryView.xaml index 4d5d1ef..98e8876 100644 --- a/Hyperbar.Windows/SecondaryView.xaml +++ b/Hyperbar.Windows/SecondaryView.xaml @@ -2,10 +2,9 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - + diff --git a/Hyperbar.Windows/SecondaryViewModel.cs b/Hyperbar.Windows/SecondaryViewModel.cs index 2cd0874..43237dc 100644 --- a/Hyperbar.Windows/SecondaryViewModel.cs +++ b/Hyperbar.Windows/SecondaryViewModel.cs @@ -10,7 +10,7 @@ public partial class SecondaryViewModel : [ObservableProperty] private int index; - public SecondaryViewModel(IViewModelTemplate template, + public SecondaryViewModel(IViewModelTemplateSelector viewModelTemplateSelector, IServiceProvider serviceProvider, IServiceFactory serviceFactory, IPublisher publisher, @@ -18,12 +18,12 @@ public partial class SecondaryViewModel : IDisposer disposer, int index) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer) { - Template = template; + ViewModelTemplateSelector = viewModelTemplateSelector; this.index = index; Add(); } - public IViewModelTemplate Template { get; } + public IViewModelTemplateSelector ViewModelTemplateSelector { get; } } \ No newline at end of file diff --git a/Hyperbar.Windows/SettingsButtonView.xaml b/Hyperbar.Windows/SettingsButtonView.xaml index 7e1292d..c2f1b8c 100644 --- a/Hyperbar.Windows/SettingsButtonView.xaml +++ b/Hyperbar.Windows/SettingsButtonView.xaml @@ -26,7 +26,7 @@ FontSize="16"> - + diff --git a/Hyperbar.Windows/SettingsButtonViewModel.cs b/Hyperbar.Windows/SettingsButtonViewModel.cs index d7aaf3c..d32c6e8 100644 --- a/Hyperbar.Windows/SettingsButtonViewModel.cs +++ b/Hyperbar.Windows/SettingsButtonViewModel.cs @@ -2,12 +2,12 @@ namespace Hyperbar.Windows; -public partial class SettingsButtonViewModel(IViewModelTemplate template, +public partial class SettingsButtonViewModel(IViewModelTemplateSelector viewModelTemplateSelector, IServiceProvider serviceProvider, IServiceFactory serviceFactory, IPublisher publisher, IDisposer disposer) : ObservableViewModel(serviceProvider, serviceFactory, publisher, disposer) { - public IViewModelTemplate Template => template; + public IViewModelTemplateSelector ViewModelTemplateSelector => viewModelTemplateSelector; } \ No newline at end of file diff --git a/Hyperbar.Windows/SettingsView.xaml b/Hyperbar.Windows/SettingsView.xaml index ae1d36c..7ff7ec5 100644 --- a/Hyperbar.Windows/SettingsView.xaml +++ b/Hyperbar.Windows/SettingsView.xaml @@ -7,9 +7,10 @@ \ No newline at end of file diff --git a/Hyperbar.Windows/SettingsView.xaml.cs b/Hyperbar.Windows/SettingsView.xaml.cs index 79d499d..5d5808c 100644 --- a/Hyperbar.Windows/SettingsView.xaml.cs +++ b/Hyperbar.Windows/SettingsView.xaml.cs @@ -4,6 +4,7 @@ using Microsoft.UI.Xaml; namespace Hyperbar.Windows; +[NavigationTarget("Settings")] public partial class SettingsView : Window { diff --git a/Hyperbar.Windows/SettingsViewModel.cs b/Hyperbar.Windows/SettingsViewModel.cs index c5781f4..3d32c21 100644 --- a/Hyperbar.Windows/SettingsViewModel.cs +++ b/Hyperbar.Windows/SettingsViewModel.cs @@ -5,18 +5,18 @@ namespace Hyperbar.Windows; public partial class SettingsViewModel : ObservableCollectionViewModel { - public SettingsViewModel(IViewModelTemplate template, + public SettingsViewModel(IViewModelTemplateSelector viewModelTemplateSelector, IServiceProvider serviceProvider, IServiceFactory serviceFactory, IPublisher publisher, ISubscriber subscriber, IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer) { - Template = template; + ViewModelTemplateSelector = viewModelTemplateSelector; Add("General"); Add("Widgets"); } - public IViewModelTemplate Template { get; } + public IViewModelTemplateSelector ViewModelTemplateSelector { get; } } diff --git a/Hyperbar.Windows/WidgetSettingsNavigationView.xaml b/Hyperbar.Windows/WidgetSettingsNavigationView.xaml index bd74876..0ce01d0 100644 --- a/Hyperbar.Windows/WidgetSettingsNavigationView.xaml +++ b/Hyperbar.Windows/WidgetSettingsNavigationView.xaml @@ -9,7 +9,7 @@ Content="Widgets"> - + diff --git a/Hyperbar.Windows/WidgetSettingsNavigationViewModel.cs b/Hyperbar.Windows/WidgetSettingsNavigationViewModel.cs index 5903da8..a48ddee 100644 --- a/Hyperbar.Windows/WidgetSettingsNavigationViewModel.cs +++ b/Hyperbar.Windows/WidgetSettingsNavigationViewModel.cs @@ -6,7 +6,4 @@ public class WidgetSettingsNavigationViewModel(IServiceProvider serviceProvider, ISubscriber subscriber, IDisposer disposer, string text) : - NavigationViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, text) -{ - -} + NavigationViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, text); diff --git a/Hyperbar.Windows/WidgetSettingsView.xaml b/Hyperbar.Windows/WidgetSettingsView.xaml new file mode 100644 index 0000000..b2b3936 --- /dev/null +++ b/Hyperbar.Windows/WidgetSettingsView.xaml @@ -0,0 +1,9 @@ + + + + + + diff --git a/Hyperbar.Windows/WidgetSettingsView.xaml.cs b/Hyperbar.Windows/WidgetSettingsView.xaml.cs new file mode 100644 index 0000000..2d84909 --- /dev/null +++ b/Hyperbar.Windows/WidgetSettingsView.xaml.cs @@ -0,0 +1,12 @@ +using Microsoft.UI.Xaml.Controls; + +namespace Hyperbar.Windows; + +public partial class WidgetSettingsView : UserControl +{ + public WidgetSettingsView() => + InitializeComponent(); + + protected WidgetSettingsViewModel ViewModel => + (WidgetSettingsViewModel)DataContext; +} diff --git a/Hyperbar.Windows/WidgetSettingsViewModel.cs b/Hyperbar.Windows/WidgetSettingsViewModel.cs new file mode 100644 index 0000000..55211da --- /dev/null +++ b/Hyperbar.Windows/WidgetSettingsViewModel.cs @@ -0,0 +1,19 @@ +using Hyperbar.UI.Windows; + +namespace Hyperbar.Windows; + +public class WidgetSettingsViewModel : + ObservableCollectionViewModel +{ + public WidgetSettingsViewModel(IViewModelTemplateSelector viewModelTemplateSelector, + IServiceProvider serviceProvider, + IServiceFactory serviceFactory, + IPublisher publisher, + ISubscriber subscriber, + IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer) + { + ViewModelTemplateSelector = viewModelTemplateSelector; + } + + public IViewModelTemplateSelector ViewModelTemplateSelector { get; } +} diff --git a/Hyperbar/Lifecycles/AppService.cs b/Hyperbar/AppService.cs similarity index 100% rename from Hyperbar/Lifecycles/AppService.cs rename to Hyperbar/AppService.cs diff --git a/Hyperbar/Lifecycles/AsyncLock.cs b/Hyperbar/AsyncLock.cs similarity index 100% rename from Hyperbar/Lifecycles/AsyncLock.cs rename to Hyperbar/AsyncLock.cs diff --git a/Hyperbar/Lifecycles/Cache.cs b/Hyperbar/Cache.cs similarity index 100% rename from Hyperbar/Lifecycles/Cache.cs rename to Hyperbar/Cache.cs diff --git a/Hyperbar/Lifecycles/Changed.cs b/Hyperbar/Changed.cs similarity index 100% rename from Hyperbar/Lifecycles/Changed.cs rename to Hyperbar/Changed.cs diff --git a/Hyperbar/Configuration/Configuration.cs b/Hyperbar/Configuration.cs similarity index 100% rename from Hyperbar/Configuration/Configuration.cs rename to Hyperbar/Configuration.cs diff --git a/Hyperbar/Configuration/ConfigurationFactory.cs b/Hyperbar/ConfigurationFactory.cs similarity index 100% rename from Hyperbar/Configuration/ConfigurationFactory.cs rename to Hyperbar/ConfigurationFactory.cs diff --git a/Hyperbar/Configuration/ConfigurationFile.cs b/Hyperbar/ConfigurationFile.cs similarity index 100% rename from Hyperbar/Configuration/ConfigurationFile.cs rename to Hyperbar/ConfigurationFile.cs diff --git a/Hyperbar/Configuration/ConfigurationInitializer.cs b/Hyperbar/ConfigurationInitializer.cs similarity index 100% rename from Hyperbar/Configuration/ConfigurationInitializer.cs rename to Hyperbar/ConfigurationInitializer.cs diff --git a/Hyperbar/Configuration/ConfigurationMonitor.cs b/Hyperbar/ConfigurationMonitor.cs similarity index 100% rename from Hyperbar/Configuration/ConfigurationMonitor.cs rename to Hyperbar/ConfigurationMonitor.cs diff --git a/Hyperbar/Configuration/ConfigurationReader.cs b/Hyperbar/ConfigurationReader.cs similarity index 100% rename from Hyperbar/Configuration/ConfigurationReader.cs rename to Hyperbar/ConfigurationReader.cs diff --git a/Hyperbar/Configuration/ConfigurationSource.cs b/Hyperbar/ConfigurationSource.cs similarity index 100% rename from Hyperbar/Configuration/ConfigurationSource.cs rename to Hyperbar/ConfigurationSource.cs diff --git a/Hyperbar/Configuration/ConfigurationValueChangedNotification.cs b/Hyperbar/ConfigurationValueChangedNotification.cs similarity index 100% rename from Hyperbar/Configuration/ConfigurationValueChangedNotification.cs rename to Hyperbar/ConfigurationValueChangedNotification.cs diff --git a/Hyperbar/Configuration/ConfigurationWriter.cs b/Hyperbar/ConfigurationWriter.cs similarity index 100% rename from Hyperbar/Configuration/ConfigurationWriter.cs rename to Hyperbar/ConfigurationWriter.cs diff --git a/Hyperbar/Lifecycles/Create.cs b/Hyperbar/Create.cs similarity index 100% rename from Hyperbar/Lifecycles/Create.cs rename to Hyperbar/Create.cs diff --git a/Hyperbar/Lifecycles/Disposer.cs b/Hyperbar/Disposer.cs similarity index 100% rename from Hyperbar/Lifecycles/Disposer.cs rename to Hyperbar/Disposer.cs diff --git a/Hyperbar/Lifecycles/Enumerate.cs b/Hyperbar/Enumerate.cs similarity index 100% rename from Hyperbar/Lifecycles/Enumerate.cs rename to Hyperbar/Enumerate.cs diff --git a/Hyperbar/Mediators/HandlerDelegate.cs b/Hyperbar/HandlerDelegate.cs similarity index 100% rename from Hyperbar/Mediators/HandlerDelegate.cs rename to Hyperbar/HandlerDelegate.cs diff --git a/Hyperbar/Mediators/HandlerWrapper.cs b/Hyperbar/HandlerWrapper.cs similarity index 100% rename from Hyperbar/Mediators/HandlerWrapper.cs rename to Hyperbar/HandlerWrapper.cs diff --git a/Hyperbar/Lifecycles/ICache.cs b/Hyperbar/ICache.cs similarity index 100% rename from Hyperbar/Lifecycles/ICache.cs rename to Hyperbar/ICache.cs diff --git a/Hyperbar/Configuration/IConfiguration.cs b/Hyperbar/IConfiguration.cs similarity index 100% rename from Hyperbar/Configuration/IConfiguration.cs rename to Hyperbar/IConfiguration.cs diff --git a/Hyperbar/Configuration/IConfigurationFactory.cs b/Hyperbar/IConfigurationFactory.cs similarity index 100% rename from Hyperbar/Configuration/IConfigurationFactory.cs rename to Hyperbar/IConfigurationFactory.cs diff --git a/Hyperbar/Configuration/IConfigurationFile.cs b/Hyperbar/IConfigurationFile.cs similarity index 100% rename from Hyperbar/Configuration/IConfigurationFile.cs rename to Hyperbar/IConfigurationFile.cs diff --git a/Hyperbar/Configuration/IConfigurationInitializer.cs b/Hyperbar/IConfigurationInitializer.cs similarity index 100% rename from Hyperbar/Configuration/IConfigurationInitializer.cs rename to Hyperbar/IConfigurationInitializer.cs diff --git a/Hyperbar/Configuration/IConfigurationMonitor.cs b/Hyperbar/IConfigurationMonitor.cs similarity index 100% rename from Hyperbar/Configuration/IConfigurationMonitor.cs rename to Hyperbar/IConfigurationMonitor.cs diff --git a/Hyperbar/Configuration/IConfigurationReader.cs b/Hyperbar/IConfigurationReader.cs similarity index 100% rename from Hyperbar/Configuration/IConfigurationReader.cs rename to Hyperbar/IConfigurationReader.cs diff --git a/Hyperbar/Configuration/IConfigurationSource.cs b/Hyperbar/IConfigurationSource.cs similarity index 100% rename from Hyperbar/Configuration/IConfigurationSource.cs rename to Hyperbar/IConfigurationSource.cs diff --git a/Hyperbar/Configuration/IConfigurationValueChangedNotification.cs b/Hyperbar/IConfigurationValueChangedNotification.cs similarity index 100% rename from Hyperbar/Configuration/IConfigurationValueChangedNotification.cs rename to Hyperbar/IConfigurationValueChangedNotification.cs diff --git a/Hyperbar/Configuration/IConfigurationWriter.cs b/Hyperbar/IConfigurationWriter.cs similarity index 100% rename from Hyperbar/Configuration/IConfigurationWriter.cs rename to Hyperbar/IConfigurationWriter.cs diff --git a/Hyperbar/Mediators/IDispatcher.cs b/Hyperbar/IDispatcher.cs similarity index 100% rename from Hyperbar/Mediators/IDispatcher.cs rename to Hyperbar/IDispatcher.cs diff --git a/Hyperbar/Lifecycles/IDisposer.cs b/Hyperbar/IDisposer.cs similarity index 100% rename from Hyperbar/Lifecycles/IDisposer.cs rename to Hyperbar/IDisposer.cs diff --git a/Hyperbar/Lifecycles/IFactory.cs b/Hyperbar/IFactory.cs similarity index 100% rename from Hyperbar/Lifecycles/IFactory.cs rename to Hyperbar/IFactory.cs diff --git a/Hyperbar/Mediators/IHandler.cs b/Hyperbar/IHandler.cs similarity index 100% rename from Hyperbar/Mediators/IHandler.cs rename to Hyperbar/IHandler.cs diff --git a/Hyperbar/Extensions/IHostBuilderExtensions.cs b/Hyperbar/IHostBuilderExtensions.cs similarity index 100% rename from Hyperbar/Extensions/IHostBuilderExtensions.cs rename to Hyperbar/IHostBuilderExtensions.cs diff --git a/Hyperbar/Lifecycles/IInitialization.cs b/Hyperbar/IInitialization.cs similarity index 100% rename from Hyperbar/Lifecycles/IInitialization.cs rename to Hyperbar/IInitialization.cs diff --git a/Hyperbar/Lifecycles/IInitializer.cs b/Hyperbar/IInitializer.cs similarity index 100% rename from Hyperbar/Lifecycles/IInitializer.cs rename to Hyperbar/IInitializer.cs diff --git a/Hyperbar/Mediators/IMediator.cs b/Hyperbar/IMediator.cs similarity index 100% rename from Hyperbar/Mediators/IMediator.cs rename to Hyperbar/IMediator.cs diff --git a/Hyperbar/Mediators/IMessage.cs b/Hyperbar/IMessage.cs similarity index 100% rename from Hyperbar/Mediators/IMessage.cs rename to Hyperbar/IMessage.cs diff --git a/Hyperbar/Lifecycles/INavigationDescriptor.cs b/Hyperbar/INavigation.cs similarity index 59% rename from Hyperbar/Lifecycles/INavigationDescriptor.cs rename to Hyperbar/INavigation.cs index 72c7013..bcdbc0e 100644 --- a/Hyperbar/Lifecycles/INavigationDescriptor.cs +++ b/Hyperbar/INavigation.cs @@ -1,6 +1,6 @@ namespace Hyperbar; -public interface INavigationDescriptor +public interface INavigation { Type Type { get; set; } } diff --git a/Hyperbar/Lifecycles/INavigationHandler.cs b/Hyperbar/INavigationHandler.cs similarity index 100% rename from Hyperbar/Lifecycles/INavigationHandler.cs rename to Hyperbar/INavigationHandler.cs diff --git a/Hyperbar/INavigationProvider.cs b/Hyperbar/INavigationProvider.cs new file mode 100644 index 0000000..a569d14 --- /dev/null +++ b/Hyperbar/INavigationProvider.cs @@ -0,0 +1,6 @@ +namespace Hyperbar; + +public interface INavigationProvider +{ + INavigation? Get(Type type); +} diff --git a/Hyperbar/INavigationTargetProvider.cs b/Hyperbar/INavigationTargetProvider.cs new file mode 100644 index 0000000..c63d5b7 --- /dev/null +++ b/Hyperbar/INavigationTargetProvider.cs @@ -0,0 +1,6 @@ +namespace Hyperbar; + +public interface INavigationTargetProvider +{ + object? Get(string name); +} \ No newline at end of file diff --git a/Hyperbar/Lifecycles/INavigationViewModel.cs b/Hyperbar/INavigationViewModel.cs similarity index 100% rename from Hyperbar/Lifecycles/INavigationViewModel.cs rename to Hyperbar/INavigationViewModel.cs diff --git a/Hyperbar/Mediators/INotification.cs b/Hyperbar/INotification.cs similarity index 100% rename from Hyperbar/Mediators/INotification.cs rename to Hyperbar/INotification.cs diff --git a/Hyperbar/Mediators/INotificationHandler.cs b/Hyperbar/INotificationHandler.cs similarity index 100% rename from Hyperbar/Mediators/INotificationHandler.cs rename to Hyperbar/INotificationHandler.cs diff --git a/Hyperbar/Lifecycles/IObservableCollectionViewModel.cs b/Hyperbar/IObservableCollectionViewModel.cs similarity index 100% rename from Hyperbar/Lifecycles/IObservableCollectionViewModel.cs rename to Hyperbar/IObservableCollectionViewModel.cs diff --git a/Hyperbar/Lifecycles/IObservableViewModel.cs b/Hyperbar/IObservableViewModel.cs similarity index 100% rename from Hyperbar/Lifecycles/IObservableViewModel.cs rename to Hyperbar/IObservableViewModel.cs diff --git a/Hyperbar/Mediators/IPipelineBehavior.cs b/Hyperbar/IPipelineBehavior.cs similarity index 100% rename from Hyperbar/Mediators/IPipelineBehavior.cs rename to Hyperbar/IPipelineBehavior.cs diff --git a/Hyperbar/Lifecycles/IProvider.cs b/Hyperbar/IProvider.cs similarity index 100% rename from Hyperbar/Lifecycles/IProvider.cs rename to Hyperbar/IProvider.cs diff --git a/Hyperbar/Lifecycles/IProxyService.cs b/Hyperbar/IProxyService.cs similarity index 100% rename from Hyperbar/Lifecycles/IProxyService.cs rename to Hyperbar/IProxyService.cs diff --git a/Hyperbar/Lifecycles/IProxyServiceCollection.cs b/Hyperbar/IProxyServiceCollection.cs similarity index 100% rename from Hyperbar/Lifecycles/IProxyServiceCollection.cs rename to Hyperbar/IProxyServiceCollection.cs diff --git a/Hyperbar/Mediators/IPublisher.cs b/Hyperbar/IPublisher.cs similarity index 100% rename from Hyperbar/Mediators/IPublisher.cs rename to Hyperbar/IPublisher.cs diff --git a/Hyperbar/Mediators/IRequest.cs b/Hyperbar/IRequest.cs similarity index 100% rename from Hyperbar/Mediators/IRequest.cs rename to Hyperbar/IRequest.cs diff --git a/Hyperbar/Extensions/IServiceCollectionExtensions.cs b/Hyperbar/IServiceCollectionExtensions.cs similarity index 95% rename from Hyperbar/Extensions/IServiceCollectionExtensions.cs rename to Hyperbar/IServiceCollectionExtensions.cs index efe3901..ccabbbe 100644 --- a/Hyperbar/Extensions/IServiceCollectionExtensions.cs +++ b/Hyperbar/IServiceCollectionExtensions.cs @@ -3,8 +3,6 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders.Physical; using Microsoft.Extensions.Hosting; -using System.Diagnostics.CodeAnalysis; -using System.Net.Mime; using System.Text.Json; namespace Hyperbar; @@ -140,7 +138,7 @@ public static class IServiceCollectionExtensions if (contract?.GetGenericArguments() is { Length: 1 } arguments) { - services.AddTransient(provider => new NavigationDescriptor + services.AddTransient(provider => new Navigation { Type = arguments[0] }); @@ -164,7 +162,7 @@ public static class IServiceCollectionExtensions services.AddKeyedTransient(contentType, key); services.AddKeyedTransient(templateType, key); - services.AddTransient(provider => new ViewModelTemplateDescriptor + services.AddTransient(provider => new ViewModelTemplate { ViewModelType = contentType, TemplateType = templateType, @@ -179,7 +177,13 @@ public static class IServiceCollectionExtensions services.AddSingleton(provider => new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type, parameters!))); + services.AddSingleton(); + services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); + services.AddSingleton(); + services.AddSingleton>(provider => new ProxyService(provider.GetRequiredService())); diff --git a/Hyperbar/Lifecycles/IServiceFactory.cs b/Hyperbar/IServiceFactory.cs similarity index 100% rename from Hyperbar/Lifecycles/IServiceFactory.cs rename to Hyperbar/IServiceFactory.cs diff --git a/Hyperbar/Lifecycles/IServiceScopeFactory.cs b/Hyperbar/IServiceScopeFactory.cs similarity index 100% rename from Hyperbar/Lifecycles/IServiceScopeFactory.cs rename to Hyperbar/IServiceScopeFactory.cs diff --git a/Hyperbar/Lifecycles/IServiceScopeProvider.cs b/Hyperbar/IServiceScopeProvider.cs similarity index 100% rename from Hyperbar/Lifecycles/IServiceScopeProvider.cs rename to Hyperbar/IServiceScopeProvider.cs diff --git a/Hyperbar/Mediators/ISubscriber.cs b/Hyperbar/ISubscriber.cs similarity index 100% rename from Hyperbar/Mediators/ISubscriber.cs rename to Hyperbar/ISubscriber.cs diff --git a/Hyperbar/Mediators/ISubscriptionManager.cs b/Hyperbar/ISubscriptionManager.cs similarity index 100% rename from Hyperbar/Mediators/ISubscriptionManager.cs rename to Hyperbar/ISubscriptionManager.cs diff --git a/Hyperbar/Templates/IViewModelTemplateDescriptor.cs b/Hyperbar/IViewModelTemplate.cs similarity index 74% rename from Hyperbar/Templates/IViewModelTemplateDescriptor.cs rename to Hyperbar/IViewModelTemplate.cs index 3492d61..f4ca5ee 100644 --- a/Hyperbar/Templates/IViewModelTemplateDescriptor.cs +++ b/Hyperbar/IViewModelTemplate.cs @@ -1,6 +1,6 @@ namespace Hyperbar; -public interface IViewModelTemplateDescriptor +public interface IViewModelTemplate { object Key { get; set; } diff --git a/Hyperbar/IViewModelTemplateProvider.cs b/Hyperbar/IViewModelTemplateProvider.cs new file mode 100644 index 0000000..67277ff --- /dev/null +++ b/Hyperbar/IViewModelTemplateProvider.cs @@ -0,0 +1,6 @@ +namespace Hyperbar; + +public interface IViewModelTemplateProvider +{ + IViewModelTemplate? Get(object key); +} diff --git a/Hyperbar/Configuration/IWritableConfiguration.cs b/Hyperbar/IWritableConfiguration.cs similarity index 100% rename from Hyperbar/Configuration/IWritableConfiguration.cs rename to Hyperbar/IWritableConfiguration.cs diff --git a/Hyperbar/Lifecycles/Insert.cs b/Hyperbar/Insert.cs similarity index 100% rename from Hyperbar/Lifecycles/Insert.cs rename to Hyperbar/Insert.cs diff --git a/Hyperbar/Lifecycles/KeyAccelerator.cs b/Hyperbar/KeyAccelerator.cs similarity index 100% rename from Hyperbar/Lifecycles/KeyAccelerator.cs rename to Hyperbar/KeyAccelerator.cs diff --git a/Hyperbar/Lifecycles/Navigate.cs b/Hyperbar/Lifecycles/Navigate.cs deleted file mode 100644 index 4865f58..0000000 --- a/Hyperbar/Lifecycles/Navigate.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace Hyperbar; - -public record Navigate(object Key) : - INotification; - -public record Navigate(TView View, object ViewModel) : - INotification; diff --git a/Hyperbar/Lifecycles/NavigateHandler.cs b/Hyperbar/Lifecycles/NavigateHandler.cs deleted file mode 100644 index 50cb2fa..0000000 --- a/Hyperbar/Lifecycles/NavigateHandler.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -namespace Hyperbar; - -public class NavigateHandler : - INotificationHandler -{ - private readonly IViewModelTemplateDescriptorProvider contentTemplateDescriptors; - private readonly IServiceProvider provider; - private readonly IPublisher publisher; - private readonly IEnumerable navigationDescriptors; - - public NavigateHandler(IServiceProvider provider, - IPublisher publisher, - IEnumerable navigationDescriptors, - IViewModelTemplateDescriptorProvider contentTemplateDescriptors) - { - this.provider = provider; - this.publisher = publisher; - this.navigationDescriptors = navigationDescriptors; - this.contentTemplateDescriptors = contentTemplateDescriptors; - } - - public async Task Handle(Navigate args, - CancellationToken cancellationToken) - { - if (contentTemplateDescriptors.Get(args.Key) - is IViewModelTemplateDescriptor contentTemplateDescriptor) - { - if (navigationDescriptors.FirstOrDefault(x => contentTemplateDescriptor.TemplateType == x.Type || - contentTemplateDescriptor.TemplateType.BaseType == x.Type) is { } navigationDescriptor) - { - if (contentTemplateDescriptor.TemplateType == navigationDescriptor.Type || - contentTemplateDescriptor.TemplateType.BaseType == navigationDescriptor.Type) - { - if (provider.GetRequiredKeyedService(contentTemplateDescriptor.TemplateType, - contentTemplateDescriptor.Key) is { } template && - provider.GetRequiredKeyedService(contentTemplateDescriptor.ViewModelType, - contentTemplateDescriptor.Key) is { } content) - { - Type navigateType = typeof(Navigate<>) - .MakeGenericType(navigationDescriptor.Type); - if (Activator.CreateInstance(navigateType, - new object[] { template, content }) is object navigate) - { - await publisher.PublishAsync(navigate, cancellationToken); - } - } - } - } - } - } -} - diff --git a/Hyperbar/Mediators/Mediator.cs b/Hyperbar/Mediator.cs similarity index 100% rename from Hyperbar/Mediators/Mediator.cs rename to Hyperbar/Mediator.cs diff --git a/Hyperbar/Mediators/Subscription.cs b/Hyperbar/Mediators/Subscription.cs deleted file mode 100644 index ce347ff..0000000 --- a/Hyperbar/Mediators/Subscription.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Hyperbar; - -public record Subscription(object Handler); diff --git a/Hyperbar/Lifecycles/Move.cs b/Hyperbar/Move.cs similarity index 100% rename from Hyperbar/Lifecycles/Move.cs rename to Hyperbar/Move.cs diff --git a/Hyperbar/Navigate.cs b/Hyperbar/Navigate.cs new file mode 100644 index 0000000..61312ff --- /dev/null +++ b/Hyperbar/Navigate.cs @@ -0,0 +1,7 @@ +namespace Hyperbar; + +public record Navigate(object Name, string? TargetName = null) : + INotification; + +public record Navigate(object Target, object View, object ViewModel) : + INotification; diff --git a/Hyperbar/NavigateHandler.cs b/Hyperbar/NavigateHandler.cs new file mode 100644 index 0000000..a03554c --- /dev/null +++ b/Hyperbar/NavigateHandler.cs @@ -0,0 +1,41 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace Hyperbar; + +public class NavigateHandler(IServiceProvider provider, + IPublisher publisher, + INavigationProvider navigationProvider, + IViewModelTemplateProvider viewModelTemplateProvider, + INavigationTargetProvider navigationTargetProvider) : + INotificationHandler +{ + public async Task Handle(Navigate args, + CancellationToken cancellationToken) + { + + if (viewModelTemplateProvider.Get(args.Name) + is IViewModelTemplate viewModelTemplate) + { + if (provider.GetRequiredKeyedService(viewModelTemplate.TemplateType, + viewModelTemplate.Key) is object view && + provider.GetRequiredKeyedService(viewModelTemplate.ViewModelType, + viewModelTemplate.Key) is object viewModel) + { + if ((args.TargetName is not null ? + navigationTargetProvider.Get(args.TargetName) : view) is object target) + { + if (navigationProvider.Get(target.GetType()) + is INavigation navigation) + { + Type navigateType = typeof(Navigate<>).MakeGenericType(navigation.Type); + if (Activator.CreateInstance(navigateType, [target, view, viewModel]) is object navigate) + { + await publisher.PublishAsync(navigate, cancellationToken); + } + } + } + } + } + } +} + diff --git a/Hyperbar/Lifecycles/NavigationDescriptor.cs b/Hyperbar/Navigation.cs similarity index 53% rename from Hyperbar/Lifecycles/NavigationDescriptor.cs rename to Hyperbar/Navigation.cs index 9da26de..80b1188 100644 --- a/Hyperbar/Lifecycles/NavigationDescriptor.cs +++ b/Hyperbar/Navigation.cs @@ -1,7 +1,7 @@ namespace Hyperbar; -public record NavigationDescriptor : - INavigationDescriptor +public record Navigation : + INavigation { public required Type Type { get; set; } } diff --git a/Hyperbar/NavigationProvider.cs b/Hyperbar/NavigationProvider.cs new file mode 100644 index 0000000..23022b9 --- /dev/null +++ b/Hyperbar/NavigationProvider.cs @@ -0,0 +1,16 @@ +namespace Hyperbar; + +public class NavigationProvider(IEnumerable navigations) : + INavigationProvider +{ + public INavigation? Get(Type type) + { + if (navigations.FirstOrDefault(x => type == x.Type || + type.BaseType == x.Type) is INavigation navigation) + { + return navigation; + } + + return default; + } +} diff --git a/Hyperbar/NavigationTargetAttribute.cs b/Hyperbar/NavigationTargetAttribute.cs new file mode 100644 index 0000000..834320d --- /dev/null +++ b/Hyperbar/NavigationTargetAttribute.cs @@ -0,0 +1,7 @@ +namespace Hyperbar.UI.Windows; + +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +public class NavigationTargetAttribute(string name) : Attribute +{ + public string Name => name; +} diff --git a/Hyperbar/NavigationTargetCollection.cs b/Hyperbar/NavigationTargetCollection.cs new file mode 100644 index 0000000..bed2bfd --- /dev/null +++ b/Hyperbar/NavigationTargetCollection.cs @@ -0,0 +1,4 @@ +namespace Hyperbar.UI.Windows; + +public class NavigationTargetCollection : + Dictionary; diff --git a/Hyperbar/NavigationTargetProvider.cs b/Hyperbar/NavigationTargetProvider.cs new file mode 100644 index 0000000..e3282ca --- /dev/null +++ b/Hyperbar/NavigationTargetProvider.cs @@ -0,0 +1,10 @@ +using Hyperbar.UI.Windows; + +namespace Hyperbar; + +public class NavigationTargetProvider(NavigationTargetCollection navigationTargets) : + INavigationTargetProvider +{ + public object? Get(string name) => + navigationTargets.TryGetValue(name, out object? target) ? target : default; +} diff --git a/Hyperbar/Lifecycles/NavigationViewModel.cs b/Hyperbar/NavigationViewModel.cs similarity index 100% rename from Hyperbar/Lifecycles/NavigationViewModel.cs rename to Hyperbar/NavigationViewModel.cs diff --git a/Hyperbar/Mediators/NotificationHandlerAttribute.cs b/Hyperbar/NotificationHandlerAttribute.cs similarity index 80% rename from Hyperbar/Mediators/NotificationHandlerAttribute.cs rename to Hyperbar/NotificationHandlerAttribute.cs index ff2b3d8..472815b 100644 --- a/Hyperbar/Mediators/NotificationHandlerAttribute.cs +++ b/Hyperbar/NotificationHandlerAttribute.cs @@ -3,5 +3,5 @@ [AttributeUsage(AttributeTargets.Class, Inherited = false)] public class NotificationHandlerAttribute(object key) : Attribute { - public object Key { get; } = key; + public object Key => key; } diff --git a/Hyperbar/Lifecycles/ObservableCollectionViewModel.cs b/Hyperbar/ObservableCollectionViewModel.cs similarity index 96% rename from Hyperbar/Lifecycles/ObservableCollectionViewModel.cs rename to Hyperbar/ObservableCollectionViewModel.cs index 9e96b63..d3b620a 100644 --- a/Hyperbar/Lifecycles/ObservableCollectionViewModel.cs +++ b/Hyperbar/ObservableCollectionViewModel.cs @@ -20,6 +20,8 @@ public partial class ObservableCollectionViewModel : INotificationHandler>, INotificationHandler>, INotificationHandler> + where TViewModel : + notnull { private readonly ObservableCollection collection = []; @@ -202,7 +204,7 @@ public partial class ObservableCollectionViewModel : Disposer.Dispose(this); } - public System.Collections.Generic.IEnumerator GetEnumerator() => + public IEnumerator GetEnumerator() => collection.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => @@ -344,18 +346,18 @@ public partial class ObservableCollectionViewModel : collection.Clear(); protected virtual void InsertItem(int index, - TViewModel value) + TViewModel item) { - Disposer.Add(this, value); - Disposer.Add(value, value, Disposable.Create(() => + Disposer.Add(this, item); + Disposer.Add(item, item, Disposable.Create(() => { - if (value is IList collection) + if (item is IList collection) { collection.Clear(); } })); - collection.Insert(index, value); + collection.Insert(index, item); } protected virtual void RemoveItem(int index) => diff --git a/Hyperbar/Lifecycles/ObservableViewModel.cs b/Hyperbar/ObservableViewModel.cs similarity index 100% rename from Hyperbar/Lifecycles/ObservableViewModel.cs rename to Hyperbar/ObservableViewModel.cs diff --git a/Hyperbar/Lifecycles/ProxyService.cs b/Hyperbar/ProxyService.cs similarity index 100% rename from Hyperbar/Lifecycles/ProxyService.cs rename to Hyperbar/ProxyService.cs diff --git a/Hyperbar/Lifecycles/ProxyServiceCollection.cs b/Hyperbar/ProxyServiceCollection.cs similarity index 100% rename from Hyperbar/Lifecycles/ProxyServiceCollection.cs rename to Hyperbar/ProxyServiceCollection.cs diff --git a/Hyperbar/Mediators/Publisher.cs b/Hyperbar/Publisher.cs similarity index 100% rename from Hyperbar/Mediators/Publisher.cs rename to Hyperbar/Publisher.cs diff --git a/Hyperbar/Lifecycles/Remove.cs b/Hyperbar/Remove.cs similarity index 100% rename from Hyperbar/Lifecycles/Remove.cs rename to Hyperbar/Remove.cs diff --git a/Hyperbar/Lifecycles/Replace.cs b/Hyperbar/Replace.cs similarity index 100% rename from Hyperbar/Lifecycles/Replace.cs rename to Hyperbar/Replace.cs diff --git a/Hyperbar/Lifecycles/Request.cs b/Hyperbar/Request.cs similarity index 100% rename from Hyperbar/Lifecycles/Request.cs rename to Hyperbar/Request.cs diff --git a/Hyperbar/Lifecycles/ServiceFactory.cs b/Hyperbar/ServiceFactory.cs similarity index 100% rename from Hyperbar/Lifecycles/ServiceFactory.cs rename to Hyperbar/ServiceFactory.cs diff --git a/Hyperbar/Lifecycles/ServiceScopeFactory.cs b/Hyperbar/ServiceScopeFactory.cs similarity index 100% rename from Hyperbar/Lifecycles/ServiceScopeFactory.cs rename to Hyperbar/ServiceScopeFactory.cs diff --git a/Hyperbar/Lifecycles/ServiceScopeProvider.cs b/Hyperbar/ServiceScopeProvider.cs similarity index 100% rename from Hyperbar/Lifecycles/ServiceScopeProvider.cs rename to Hyperbar/ServiceScopeProvider.cs diff --git a/Hyperbar/Lifecycles/StartProcess.cs b/Hyperbar/StartProcess.cs similarity index 100% rename from Hyperbar/Lifecycles/StartProcess.cs rename to Hyperbar/StartProcess.cs diff --git a/Hyperbar/Mediators/Subscriber.cs b/Hyperbar/Subscriber.cs similarity index 100% rename from Hyperbar/Mediators/Subscriber.cs rename to Hyperbar/Subscriber.cs diff --git a/Hyperbar/SubscriptionCollection.cs b/Hyperbar/SubscriptionCollection.cs new file mode 100644 index 0000000..49a8852 --- /dev/null +++ b/Hyperbar/SubscriptionCollection.cs @@ -0,0 +1,6 @@ +using System.Collections.Concurrent; + +namespace Hyperbar; + +public class SubscriptionCollection : + ConcurrentDictionary>; diff --git a/Hyperbar/Mediators/SubscriptionManager.cs b/Hyperbar/SubscriptionManager.cs similarity index 93% rename from Hyperbar/Mediators/SubscriptionManager.cs rename to Hyperbar/SubscriptionManager.cs index 6f93535..e6bfe5d 100644 --- a/Hyperbar/Mediators/SubscriptionManager.cs +++ b/Hyperbar/SubscriptionManager.cs @@ -1,13 +1,10 @@ -using System.Collections.Concurrent; -using System.Reflection; +using System.Reflection; namespace Hyperbar; -public class SubscriptionManager : +public class SubscriptionManager(SubscriptionCollection subscriptions) : ISubscriptionManager { - private readonly ConcurrentDictionary> subscriptions = new(); - public IEnumerable GetHandlers(Type notificationType, object key) { if (subscriptions.TryGetValue($"{key?.ToString()}:{notificationType}", diff --git a/Hyperbar/Templates/IViewModelTemplateDescriptorProvider.cs b/Hyperbar/Templates/IViewModelTemplateDescriptorProvider.cs deleted file mode 100644 index e29d180..0000000 --- a/Hyperbar/Templates/IViewModelTemplateDescriptorProvider.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Hyperbar; - -public interface IViewModelTemplateDescriptorProvider -{ - IViewModelTemplateDescriptor? Get(object key); -} diff --git a/Hyperbar/Templates/ViewModelTemplateDescriptorProvider.cs b/Hyperbar/Templates/ViewModelTemplateDescriptorProvider.cs deleted file mode 100644 index 166c790..0000000 --- a/Hyperbar/Templates/ViewModelTemplateDescriptorProvider.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Hyperbar; - -public class ViewModelTemplateDescriptorProvider(IEnumerable descriptors) : - IViewModelTemplateDescriptorProvider -{ - public IViewModelTemplateDescriptor? Get(object key) - { - if (descriptors.FirstOrDefault(x => x.Key.Equals(key)) - is IViewModelTemplateDescriptor descriptor) - { - return descriptor; - } - - return default; - } -} diff --git a/Hyperbar/Mediators/Unit.cs b/Hyperbar/Unit.cs similarity index 100% rename from Hyperbar/Mediators/Unit.cs rename to Hyperbar/Unit.cs diff --git a/Hyperbar/Templates/ViewModelTemplateDescriptor.cs b/Hyperbar/ViewModelTemplate.cs similarity index 69% rename from Hyperbar/Templates/ViewModelTemplateDescriptor.cs rename to Hyperbar/ViewModelTemplate.cs index 291fd03..ef3a475 100644 --- a/Hyperbar/Templates/ViewModelTemplateDescriptor.cs +++ b/Hyperbar/ViewModelTemplate.cs @@ -1,7 +1,7 @@ namespace Hyperbar; -public record ViewModelTemplateDescriptor : - IViewModelTemplateDescriptor +public record ViewModelTemplate : + IViewModelTemplate { public required Type ViewModelType { get; set; } diff --git a/Hyperbar/ViewModelTemplateProvider.cs b/Hyperbar/ViewModelTemplateProvider.cs new file mode 100644 index 0000000..45241ca --- /dev/null +++ b/Hyperbar/ViewModelTemplateProvider.cs @@ -0,0 +1,15 @@ +namespace Hyperbar; +public class ViewModelTemplateProvider(IEnumerable viewModelTemplates) : + IViewModelTemplateProvider +{ + public IViewModelTemplate? Get(object key) + { + if (viewModelTemplates.FirstOrDefault(x => x.Key.Equals(key)) + is IViewModelTemplate viewModelTemplate) + { + return viewModelTemplate; + } + + return default; + } +} diff --git a/Hyperbar/Lifecycles/VirtualKey.cs b/Hyperbar/VirtualKey.cs similarity index 100% rename from Hyperbar/Lifecycles/VirtualKey.cs rename to Hyperbar/VirtualKey.cs diff --git a/Hyperbar/Configuration/WritableConfiguration.cs b/Hyperbar/WritableConfiguration.cs similarity index 100% rename from Hyperbar/Configuration/WritableConfiguration.cs rename to Hyperbar/WritableConfiguration.cs