Rework navigation so we can resolve by key now

This commit is contained in:
Dan Clark
2024-11-17 23:09:26 +00:00
parent 796ef41e3f
commit 7a9028bbeb
26 changed files with 371 additions and 88 deletions
+58
View File
@@ -0,0 +1,58 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Toolkit.Foundation;
namespace Toolkit.WinUI;
public class ContentControlHandler :
IHandler<NavigateTemplateEventArgs>
{
public void Handle(NavigateTemplateEventArgs args)
{
if (args.Region is ContentControl contentControl)
{
if (args.Template is Control control)
{
TaskCompletionSource taskCompletionSource = new();
void HandleLoaded(object? sender, RoutedEventArgs args)
{
control.Loaded -= HandleLoaded;
if (control.DataContext is object content)
{
if (content is IActivation activation)
{
activation.IsActive = true;
}
}
taskCompletionSource.SetResult();
}
void HandleUnloaded(object? sender, RoutedEventArgs args)
{
control.Unloaded -= HandleLoaded;
if (control.DataContext is object content)
{
if (content is IActivation activation)
{
activation.IsActive = false;
}
if (content is IDisposable disposable)
{
disposable.Dispose();
}
}
}
control.Loaded += HandleLoaded;
control.Unloaded += HandleUnloaded;
control.DataContext = args.Content;
contentControl.Content = null;
contentControl.Content = control;
}
}
}
}
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml.Controls;
using Toolkit.Foundation;
namespace Toolkit.WinUI;
@@ -12,6 +13,9 @@ public static class IServiceCollectionExtensions
services.AddSingleton<IWindowRegistry, WindowRegistry>();
services.AddTransient<IContentTemplate, ContentTemplate>();
services.AddTransient<INavigationRegion, NavigationRegion>();
services.AddHandler<NavigateTemplateEventArgs, ContentControlHandler>(nameof(ContentControl));
services.AddTransient((Func<IServiceProvider, IProxyServiceCollection<IComponentBuilder>>)(provider =>
new ProxyServiceCollection<IComponentBuilder>(services =>
@@ -21,4 +25,4 @@ public static class IServiceCollectionExtensions
return services;
}
}
}
+28
View File
@@ -0,0 +1,28 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Toolkit.Foundation;
namespace Toolkit.WinUI;
public class NavigationRegion(INavigationRegionCollection collection) :
INavigationRegion
{
public void Register(string name,
object target)
{
if (target is Control control)
{
if (!collection.ContainsKey(name))
{
collection.Add(name, control);
void HandleUnloaded(object? sender, RoutedEventArgs args)
{
control.Unloaded -= HandleUnloaded;
collection.Remove(name);
}
control.Unloaded += HandleUnloaded;
}
}
}
}
+9
View File
@@ -0,0 +1,9 @@
using Microsoft.UI.Xaml.Controls;
namespace Toolkit.WinUI;
public class PageControl :
Page
{
}
+39 -43
View File
@@ -23,56 +23,52 @@ public class TemplateControl :
if (DataContext is IObservableViewModel observableViewModel)
{
if (observableViewModel.Provider is IServiceProvider provider)
if (observableViewModel.Provider is IServiceProvider provider &&
provider.GetRequiredKeyedService<IContentTemplateDescriptor>(DataContext.GetType().Name.Replace("ViewModel", ""))
is IContentTemplateDescriptor descriptor &&
provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key)
is FrameworkElement control)
{
if (provider.GetRequiredKeyedService<IContentTemplateDescriptor>(DataContext.GetType().Name.Replace("ViewModel", ""))
is IContentTemplateDescriptor descriptor)
void HandleLoaded(object? sender, RoutedEventArgs args)
{
if (provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key)
is FrameworkElement control)
control.Loaded -= HandleLoaded;
if (control.DataContext is object content)
{
void HandleLoaded(object? sender, RoutedEventArgs args)
if (content is IActivation activation)
{
control.Loaded -= HandleLoaded;
if (control.DataContext is object content)
{
if (content is IActivation activation)
{
activation.IsActive = true;
}
}
activation.IsActive = true;
}
void HandleDataContextChanged(FrameworkElement? sender, DataContextChangedEventArgs args)
{
if (control.DataContext is object content)
{
if (content is IActivation activation)
{
activation.IsActive = true;
}
}
}
void HandleUnloaded(object? sender, RoutedEventArgs args)
{
control.Unloaded -= HandleUnloaded;
if (control.DataContext is object content)
{
if (content is IActivation activation)
{
activation.IsActive = false;
}
}
}
control.Loaded += HandleLoaded;
control.Unloaded += HandleUnloaded;
control.DataContextChanged += HandleDataContextChanged;
Content = control;
}
}
void HandleDataContextChanged(FrameworkElement? sender, DataContextChangedEventArgs args)
{
if (control.DataContext is object content)
{
if (content is IActivation activation)
{
activation.IsActive = true;
}
}
}
void HandleUnloaded(object? sender, RoutedEventArgs args)
{
control.Unloaded -= HandleUnloaded;
if (control.DataContext is object content)
{
if (content is IActivation activation)
{
activation.IsActive = false;
}
}
}
control.Loaded += HandleLoaded;
control.Unloaded += HandleUnloaded;
control.DataContextChanged += HandleDataContextChanged;
Content = control;
}
}
}
+1 -1
View File
@@ -20,7 +20,7 @@
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1742" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.240923002" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Toolkit.Windows\Toolkit.Windows.csproj" />
</ItemGroup>
+1 -1
View File
@@ -11,4 +11,4 @@ public class WinUIDispatcher :
DispatcherQueue.GetForCurrentThread().TryEnqueue(action.Invoke);
return Task.CompletedTask;
}
}
}