Inner scope navigation

This commit is contained in:
TheXamlGuy
2024-02-13 22:11:29 +00:00
parent 6e738becd4
commit 9fe2317c4f
30 changed files with 189 additions and 130 deletions
+2 -1
View File
@@ -28,7 +28,8 @@ public sealed class NavigateAction :
set => SetValue(TargetNameProperty, value); set => SetValue(TargetNameProperty, value);
} }
public object Execute(object sender, object parameter) public object Execute(object sender,
object parameter)
{ {
if (sender is FrameworkElement frameworkElement) if (sender is FrameworkElement frameworkElement)
{ {
@@ -7,6 +7,11 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="WidgetNavigationView.xaml" />
<None Remove="WidgetSettingsNavigationView.xaml" />
<None Remove="WidgetSettingsView.xaml" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240124002-experimental2" /> <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240124002-experimental2" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26031-preview" /> <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26031-preview" />
@@ -18,4 +23,18 @@
<ProjectReference Include="..\Hyperbar.Widget\Hyperbar.Widget.csproj" /> <ProjectReference Include="..\Hyperbar.Widget\Hyperbar.Widget.csproj" />
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" /> <ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Page Update="WidgetSettingsNavigationView.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="WidgetNavigationView.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="WidgetSettingsView.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
</Project> </Project>
@@ -9,9 +9,6 @@ public static class IServiceCollectionExtensions
{ {
public static IServiceCollection AddWidgetWindows(this IServiceCollection services) public static IServiceCollection AddWidgetWindows(this IServiceCollection services)
{ {
// 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((Func<IServiceProvider, IProxyServiceCollection<IWidgetBuilder>>)(provider => services.AddTransient((Func<IServiceProvider, IProxyServiceCollection<IWidgetBuilder>>)(provider =>
new ProxyServiceCollection<IWidgetBuilder>(services => new ProxyServiceCollection<IWidgetBuilder>(services =>
{ {
@@ -25,6 +22,11 @@ public static class IServiceCollectionExtensions
services.AddHandler<KeyAcceleratorHandler>(); services.AddHandler<KeyAcceleratorHandler>();
services.AddHandler<StartProcessHandler>(); services.AddHandler<StartProcessHandler>();
services.AddTransient<IViewModelContentBinder, ViewModelContentBinder>();
services.AddNavigationHandler<WindowHandler>();
services.AddNavigationHandler<ContentControlHandler>();
services.AddHandler<WidgetViewModelEnumerator>(); services.AddHandler<WidgetViewModelEnumerator>();
services.AddTransient<IWidgetView, WidgetView>(); services.AddTransient<IWidgetView, WidgetView>();
@@ -33,6 +35,9 @@ public static class IServiceCollectionExtensions
services.AddContentTemplate<WidgetButtonViewModel, WidgetButtonView>(); services.AddContentTemplate<WidgetButtonViewModel, WidgetButtonView>();
services.AddContentTemplate<WidgetSplitButtonViewModel, WidgetSplitButtonView>(); services.AddContentTemplate<WidgetSplitButtonViewModel, WidgetSplitButtonView>();
services.AddContentTemplate<WidgetSettingsNavigationViewModel, WidgetSettingsNavigationView>();
services.AddContentTemplate<WidgetSettingsViewModel, WidgetSettingsView>("WidgetSettings");
}))); })));
return services; return services;
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<NavigationViewItem <NavigationViewItem
x:Class="Hyperbar.Windows.WidgetSettingsNavigationView" x:Class="Hyperbar.Widget.Windows.WidgetNavigationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core" xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:ui="using:Hyperbar.UI.Windows" xmlns:ui="using:Hyperbar.UI.Windows"
Content="Widgets" Content="Widgets"
IsExpanded="True"
MenuItemsSource="{Binding}" MenuItemsSource="{Binding}"
SelectsOnInvoked="False"> SelectsOnInvoked="False">
<interactivity:Interaction.Behaviors> <interactivity:Interaction.Behaviors>
@@ -0,0 +1,13 @@
using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Widget.Windows;
public partial class WidgetNavigationView :
NavigationViewItem
{
public WidgetNavigationView() =>
InitializeComponent();
protected WidgetNavigationViewModel ViewModel =>
(WidgetNavigationViewModel)DataContext;
}
@@ -0,0 +1,16 @@
using Hyperbar.UI.Windows;
namespace Hyperbar.Widget.Windows;
[NotificationHandler(nameof(WidgetNavigationViewModel))]
public class WidgetNavigationViewModel(IViewModelTemplateSelector viewModelTemplateSelector,
IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer,
string text) :
NavigationViewModel<WidgetSettingsNavigationViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer, text)
{
public IViewModelTemplateSelector ViewModelTemplateSelector => viewModelTemplateSelector;
}
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<NavigationViewItem
x:Class="Hyperbar.Widget.Windows.WidgetSettingsNavigationView"
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"
Content="{Binding Text}">
<interactivity:Interaction.Behaviors>
<interactions:EventTriggerBehavior EventName="Tapped">
<ui:NavigateAction Name="WidgetSettings" TargetName="Settings" />
</interactions:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</NavigationViewItem>
@@ -0,0 +1,10 @@
using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Widget.Windows;
public sealed partial class WidgetSettingsNavigationView :
NavigationViewItem
{
public WidgetSettingsNavigationView() =>
InitializeComponent();
}
@@ -1,8 +1,6 @@
using Hyperbar.UI.Windows; namespace Hyperbar.Widget.Windows;
namespace Hyperbar.Windows; public class WidgetSettingsNavigationViewModel(IServiceProvider serviceProvider,
public class WidgetNavigationViewModel(IServiceProvider serviceProvider,
IServiceFactory serviceFactory, IServiceFactory serviceFactory,
IPublisher publisher, IPublisher publisher,
ISubscriber subscriber, ISubscriber subscriber,
@@ -0,0 +1,22 @@
using Microsoft.Extensions.DependencyInjection;
namespace Hyperbar.Widget.Windows;
public class WidgetSettingsNavigationViewModelEnumerator(IPublisher publisher,
IWidgetHostCollection widgetHosts) :
INotificationHandler<Enumerate<WidgetSettingsNavigationViewModel>>
{
public async Task Handle(Enumerate<WidgetSettingsNavigationViewModel> args,
CancellationToken cancellationToken = default)
{
foreach (IWidgetHost host in widgetHosts)
{
if (host.Services.GetService<IServiceFactory>() is IServiceFactory serviceFactory)
{
await publisher.PublishAsync(new Create<WidgetSettingsNavigationViewModel>(serviceFactory
.Create<WidgetSettingsNavigationViewModel>(host.Configuration.Name)),
nameof(WidgetNavigationViewModel), cancellationToken);
}
}
}
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<UserControl <UserControl
x:Class="Hyperbar.Windows.WidgetSettingsView" x:Class="Hyperbar.Widget.Windows.WidgetSettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid> <Grid>
@@ -1,6 +1,6 @@
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Windows; namespace Hyperbar.Widget.Windows;
public partial class WidgetSettingsView : UserControl public partial class WidgetSettingsView : UserControl
{ {
@@ -1,6 +1,6 @@
using Hyperbar.UI.Windows; using Hyperbar.UI.Windows;
namespace Hyperbar.Windows; namespace Hyperbar.Widget.Windows;
public class WidgetSettingsViewModel(IViewModelTemplateSelector viewModelTemplateSelector, public class WidgetSettingsViewModel(IViewModelTemplateSelector viewModelTemplateSelector,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
@@ -10,5 +10,5 @@ public class WidgetSettingsViewModel(IViewModelTemplateSelector viewModelTemplat
IDisposer disposer) : IDisposer disposer) :
ObservableCollectionViewModel<IObservableViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer) ObservableCollectionViewModel<IObservableViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{ {
public IViewModelTemplateSelector ViewModelTemplateSelector { get; } = viewModelTemplateSelector; public IViewModelTemplateSelector ViewModelTemplateSelector => viewModelTemplateSelector;
} }
+13 -5
View File
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Configuration; using Hyperbar.UI.Windows;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using System.Reflection; using System.Reflection;
@@ -31,13 +32,14 @@ public class WidgetBuilder :
new ServiceFactory((type, parameters) => new ServiceFactory((type, parameters) =>
ActivatorUtilities.CreateInstance(provider, type, parameters!))); ActivatorUtilities.CreateInstance(provider, type, parameters!)));
services.AddScoped<SubscriptionCollection>(); services.AddSingleton<SubscriptionCollection>();
services.AddScoped<ISubscriptionManager, SubscriptionManager>(); services.AddSingleton<ISubscriptionManager, SubscriptionManager>();
services.AddTransient<ISubscriber, Subscriber>(); services.AddTransient<ISubscriber, Subscriber>();
services.AddTransient<IPublisher, Publisher>(); services.AddTransient<IPublisher, Publisher>();
services.AddScoped<IMediator, Mediator>(); services.AddTransient<IMediator, Mediator>();
services.AddScoped<IDisposer, Disposer>(); services.AddSingleton<IDisposer, Disposer>();
services.AddHandler<WidgetAvailabilityChangedHandler>(); services.AddHandler<WidgetAvailabilityChangedHandler>();
services.AddValueChangedNotification<WidgetConfiguration, services.AddValueChangedNotification<WidgetConfiguration,
@@ -45,6 +47,12 @@ public class WidgetBuilder :
{ {
args.Value = config.IsEnabled; args.Value = config.IsEnabled;
}); });
services.AddTransient<INavigationProvider, NavigationProvider>();
services.AddSingleton<NavigationTargetCollection>();
services.AddTransient<INavigationTargetProvider, NavigationTargetProvider>();
services.AddHandler<NavigateHandler>();
}); });
} }
@@ -17,6 +17,7 @@ public class WidgetExtensionHandler(IServiceProvider provider,
{ {
args.AddSingleton(widgetExtension.Assembly); args.AddSingleton(widgetExtension.Assembly);
args.AddTransient(_ => provider.GetRequiredService<IProxyService<IPublisher>>()); args.AddTransient(_ => provider.GetRequiredService<IProxyService<IPublisher>>());
args.AddTransient(_ => provider.GetRequiredService<IProxyService<INavigationTargetProvider>>());
args.AddRange(typedServices.Services); args.AddRange(typedServices.Services);
}); });
+3 -10
View File
@@ -38,9 +38,8 @@ public partial class App :
services.AddSingleton((IDispatcher)new Dispatcher(DispatcherQueue.GetForCurrentThread())); services.AddSingleton((IDispatcher)new Dispatcher(DispatcherQueue.GetForCurrentThread()));
services.AddTransient<INavigationProvider, NavigationProvider>(); services.AddNavigationHandler<WindowHandler>();
services.AddSingleton<NavigationTargetCollection>(); services.AddNavigationHandler<ContentControlHandler>();
services.AddTransient<INavigationTargetProvider, NavigationTargetProvider>();
services.AddTransient<IViewModelContentBinder, ViewModelContentBinder>(); services.AddTransient<IViewModelContentBinder, ViewModelContentBinder>();
@@ -53,9 +52,6 @@ public partial class App :
args.Placement = DesktopApplicationBarPlacemenet.Top; args.Placement = DesktopApplicationBarPlacemenet.Top;
}); });
services.AddNavigationHandler<WindowHandler>();
services.AddNavigationHandler<ContentControlHandler>();
services.AddSingleton<DesktopApplicationBar>(); services.AddSingleton<DesktopApplicationBar>();
services.AddContentTemplate<ApplicationBarViewModel, ApplicationBarView>(); services.AddContentTemplate<ApplicationBarViewModel, ApplicationBarView>();
services.AddContentTemplate<PrimaryViewModel, PrimaryView>(); services.AddContentTemplate<PrimaryViewModel, PrimaryView>();
@@ -65,12 +61,9 @@ public partial class App :
services.AddContentTemplate<SettingsViewModel, SettingsView>("Settings"); services.AddContentTemplate<SettingsViewModel, SettingsView>("Settings");
services.AddContentTemplate<GeneralSettingsNavigationViewModel, GeneralSettingsNavigationView>(); services.AddContentTemplate<GeneralSettingsNavigationViewModel, GeneralSettingsNavigationView>();
services.AddContentTemplate<WidgetSettingsNavigationViewModel, WidgetSettingsNavigationView>();
services.AddContentTemplate<WidgetNavigationViewModel, WidgetNavigationView>(); services.AddContentTemplate<WidgetNavigationViewModel, WidgetNavigationView>();
services.AddContentTemplate<WidgetSettingsViewModel, WidgetSettingsView>("WidgetSettings"); services.AddHandler<WidgetSettingsNavigationViewModelEnumerator>();
services.AddHandler<WidgetNavigationViewModelEnumerator>();
services.AddTransient<IInitializer, AppInitializer>(); services.AddTransient<IInitializer, AppInitializer>();
}) })
.Build(); .Build();
-18
View File
@@ -20,9 +20,6 @@
<None Remove="SecondaryView.xaml" /> <None Remove="SecondaryView.xaml" />
<None Remove="SettingsButtonView.xaml" /> <None Remove="SettingsButtonView.xaml" />
<None Remove="SettingsView.xaml" /> <None Remove="SettingsView.xaml" />
<None Remove="WidgetNavigationView.xaml" />
<None Remove="WidgetSettingsNavigationView.xaml" />
<None Remove="WidgetSettingsView.xaml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Assets\SplashScreen.scale-200.png" /> <Content Include="Assets\SplashScreen.scale-200.png" />
@@ -59,26 +56,11 @@
<ProjectReference Include="..\Hyperbar.Widget\Hyperbar.Widget.csproj" /> <ProjectReference Include="..\Hyperbar.Widget\Hyperbar.Widget.csproj" />
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" /> <ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Page Update="WidgetNavigationView.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="WidgetSettingsView.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Page Update="GeneralSettingsNavigationView.xaml"> <Page Update="GeneralSettingsNavigationView.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Page Update="WidgetSettingsNavigationView.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Page Update="SettingsView.xaml"> <Page Update="SettingsView.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
+1 -3
View File
@@ -2,9 +2,7 @@
<Window <Window
x:Class="Hyperbar.Windows.SettingsView" x:Class="Hyperbar.Windows.SettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity">
<Window.SystemBackdrop> <Window.SystemBackdrop>
<MicaBackdrop /> <MicaBackdrop />
</Window.SystemBackdrop> </Window.SystemBackdrop>
+2 -1
View File
@@ -1,4 +1,5 @@
using Hyperbar.UI.Windows; using Hyperbar.UI.Windows;
using Hyperbar.Widget.Windows;
namespace Hyperbar.Windows; namespace Hyperbar.Windows;
@@ -15,7 +16,7 @@ public partial class SettingsViewModel :
ViewModelTemplateSelector = viewModelTemplateSelector; ViewModelTemplateSelector = viewModelTemplateSelector;
Add<GeneralSettingsNavigationViewModel>("General"); Add<GeneralSettingsNavigationViewModel>("General");
Add<WidgetSettingsNavigationViewModel>("Widgets"); Add<WidgetNavigationViewModel>("Widgets");
} }
public IViewModelTemplateSelector ViewModelTemplateSelector { get; } public IViewModelTemplateSelector ViewModelTemplateSelector { get; }
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<NavigationViewItem
x:Class="Hyperbar.Windows.WidgetNavigationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Content="dsfsdvfsd" />
@@ -1,11 +0,0 @@
using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Windows;
public sealed partial class WidgetNavigationView :
NavigationViewItem
{
public WidgetNavigationView() =>
InitializeComponent();
}
@@ -1,15 +0,0 @@
using System.Security.Policy;
namespace Hyperbar.Windows;
public class WidgetNavigationViewModelEnumerator(IServiceFactory serviceFactory,
IPublisher publisher) :
INotificationHandler<Enumerate<WidgetNavigationViewModel>>
{
public async Task Handle(Enumerate<WidgetNavigationViewModel> args,
CancellationToken cancellationToken = default)
{
await publisher.PublishAsync(new Create<WidgetNavigationViewModel>(serviceFactory
.Create<WidgetNavigationViewModel>("fo")), nameof(WidgetSettingsNavigationViewModel), cancellationToken);
}
}
@@ -1,13 +0,0 @@
using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Windows;
public partial class WidgetSettingsNavigationView :
NavigationViewItem
{
public WidgetSettingsNavigationView() =>
InitializeComponent();
protected WidgetSettingsNavigationViewModel ViewModel =>
(WidgetSettingsNavigationViewModel)DataContext;
}
@@ -1,16 +0,0 @@
using Hyperbar.UI.Windows;
namespace Hyperbar.Windows;
[NotificationHandler(nameof(WidgetSettingsNavigationViewModel))]
public class WidgetSettingsNavigationViewModel(IViewModelTemplateSelector viewModelTemplateSelector,
IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer,
string text) :
NavigationViewModel<WidgetNavigationViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer, text)
{
public IViewModelTemplateSelector ViewModelTemplateSelector => viewModelTemplateSelector;
}
+3
View File
@@ -3,4 +3,7 @@
public interface INavigationTargetProvider public interface INavigationTargetProvider
{ {
object? Get(string name); object? Get(string name);
bool TryGet(string name,
out object? value);
} }
+8 -1
View File
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection; using Hyperbar.UI.Windows;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.FileProviders.Physical; using Microsoft.Extensions.FileProviders.Physical;
@@ -187,8 +188,14 @@ public static class IServiceCollectionExtensions
services.AddSingleton<IProxyService<IPublisher>>(provider => services.AddSingleton<IProxyService<IPublisher>>(provider =>
new ProxyService<IPublisher>(provider.GetRequiredService<IPublisher>())); new ProxyService<IPublisher>(provider.GetRequiredService<IPublisher>()));
services.AddSingleton<IProxyService<INavigationTargetProvider>>(provider =>
new ProxyService<INavigationTargetProvider>(provider.GetRequiredService<INavigationTargetProvider>()));
services.AddSingleton<IDisposer, Disposer>(); services.AddSingleton<IDisposer, Disposer>();
services.AddTransient<INavigationProvider, NavigationProvider>();
services.AddSingleton<NavigationTargetCollection>();
services.AddTransient<INavigationTargetProvider, NavigationTargetProvider>();
services.AddHandler<NavigateHandler>(); services.AddHandler<NavigateHandler>();
return services; return services;
+9 -3
View File
@@ -6,7 +6,8 @@ public class NavigateHandler(IServiceProvider provider,
IPublisher publisher, IPublisher publisher,
INavigationProvider navigationProvider, INavigationProvider navigationProvider,
IViewModelTemplateProvider viewModelTemplateProvider, IViewModelTemplateProvider viewModelTemplateProvider,
INavigationTargetProvider navigationTargetProvider) : INavigationTargetProvider navigationTargetProvider,
IProxyService<INavigationTargetProvider> proxyNavigationTargetProvider) :
INotificationHandler<Navigate> INotificationHandler<Navigate>
{ {
public async Task Handle(Navigate args, public async Task Handle(Navigate args,
@@ -20,8 +21,13 @@ public class NavigateHandler(IServiceProvider provider,
provider.GetRequiredKeyedService(viewModelTemplate.ViewModelType, provider.GetRequiredKeyedService(viewModelTemplate.ViewModelType,
viewModelTemplate.Key) is object viewModel) viewModelTemplate.Key) is object viewModel)
{ {
if ((args.TargetName is not null ? object? target = args.TargetName is not null
navigationTargetProvider.Get(args.TargetName) : view) is object target) ? navigationTargetProvider.TryGet(args.TargetName, out target) || proxyNavigationTargetProvider.Proxy.TryGet(args.TargetName, out target)
? target
: null
: view;
if (target is not null)
{ {
if (navigationProvider.Get(target.GetType()) if (navigationProvider.Get(target.GetType())
is INavigation navigation) is INavigation navigation)
+16
View File
@@ -7,4 +7,20 @@ public class NavigationTargetProvider(NavigationTargetCollection navigationTarge
{ {
public object? Get(string name) => public object? Get(string name) =>
navigationTargets.TryGetValue(name, out object? target) ? target : default; navigationTargets.TryGetValue(name, out object? target) ? target : default;
public bool TryGet(string name,
out object? value)
{
if (navigationTargets.TryGetValue(name,
out object? target))
{
value = target;
return true;
}
else
{
value = null;
return false;
}
}
} }
+19 -13
View File
@@ -12,16 +12,18 @@ public class Publisher(ISubscriptionManager subscriptionManager,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
where TNotification : where TNotification :
INotification, INotification,
new() => PublishAsync(new TNotification(), args => dispatcher.InvokeAsync(async () => await args()), new() => PublishAsync(new TNotification(), args =>
key, cancellationToken); dispatcher.InvokeAsync(async () => await args()),
key, cancellationToken);
public Task PublishAsync<TNotification>(TNotification notification, public Task PublishAsync<TNotification>(TNotification notification,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
where TNotification : where TNotification :
INotification INotification
{ {
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()), return PublishAsync(notification, args =>
null, cancellationToken); dispatcher.InvokeAsync(async () => await args()),
null, cancellationToken);
} }
public Task PublishAsync<TNotification>(TNotification notification, public Task PublishAsync<TNotification>(TNotification notification,
@@ -30,8 +32,9 @@ public class Publisher(ISubscriptionManager subscriptionManager,
where TNotification : where TNotification :
INotification INotification
{ {
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()), return PublishAsync(notification, args =>
key, cancellationToken); dispatcher.InvokeAsync(async () => await args()),
key, cancellationToken);
} }
public Task PublishAsync(object notification, public Task PublishAsync(object notification,
@@ -43,7 +46,8 @@ public class Publisher(ISubscriptionManager subscriptionManager,
List<object?> handlers = provider.GetServices(typeof(INotificationHandler<>) List<object?> handlers = provider.GetServices(typeof(INotificationHandler<>)
.MakeGenericType(notificationType)).ToList(); .MakeGenericType(notificationType)).ToList();
foreach (object? handler in subscriptionManager.GetHandlers(notificationType, key)) foreach (object? handler in subscriptionManager
.GetHandlers(notificationType, key!))
{ {
handlers.Add(handler); handlers.Add(handler);
} }
@@ -58,8 +62,8 @@ public class Publisher(ISubscriptionManager subscriptionManager,
if (handleMethod is not null) if (handleMethod is not null)
{ {
marshal(() => (Task)handleMethod.Invoke(handler, new object[] { notification, marshal(() => (Task)handleMethod.Invoke(handler, new object[]
cancellationToken })!); { notification, cancellationToken })!);
} }
} }
} }
@@ -70,14 +74,16 @@ public class Publisher(ISubscriptionManager subscriptionManager,
public Task PublishAsync<TNotification>(CancellationToken cancellationToken = default) public Task PublishAsync<TNotification>(CancellationToken cancellationToken = default)
where TNotification : where TNotification :
INotification, INotification,
new() => PublishAsync(new TNotification(), args => dispatcher.InvokeAsync(async () => await args()), new() => PublishAsync(new TNotification(), args =>
null, cancellationToken); dispatcher.InvokeAsync(async () => await args()),
null, cancellationToken);
public Task PublishAsync(object notification, public Task PublishAsync(object notification,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
return PublishAsync(notification, args => dispatcher.InvokeAsync(async () => await args()), return PublishAsync(notification, args =>
null, cancellationToken); dispatcher.InvokeAsync(async () => await args()),
null, cancellationToken);
} }
} }
-1
View File
@@ -7,7 +7,6 @@ public class SubscriptionManager(SubscriptionCollection subscriptions) :
{ {
public IEnumerable<object?> GetHandlers(Type notificationType, object key) public IEnumerable<object?> GetHandlers(Type notificationType, object key)
{ {
var d = subscriptions;
if (subscriptions.TryGetValue($"{key?.ToString()}:{notificationType}", if (subscriptions.TryGetValue($"{key?.ToString()}:{notificationType}",
out List<WeakReference>? subscribers)) out List<WeakReference>? subscribers))
{ {