Get ContentControl navigation working

This commit is contained in:
TheXamlGuy
2024-02-11 18:09:22 +00:00
parent 565c6866d8
commit 812556f8b0
133 changed files with 335 additions and 195 deletions
@@ -0,0 +1,9 @@
using Microsoft.UI.Xaml;
namespace Hyperbar.UI.Windows;
public interface IViewModelContentBinder
{
void Bind(FrameworkElement view,
object context);
}
@@ -1,6 +0,0 @@
namespace Hyperbar.UI.Windows;
public interface IViewModelTemplate
{
}
@@ -0,0 +1,6 @@
namespace Hyperbar.UI.Windows;
public interface IViewModelTemplateSelector
{
}
+16 -6
View File
@@ -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();
}
}
@@ -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<NavigationTargetAttribute>()
is IEnumerable<NavigationTargetAttribute> 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;
}
}
}
}
}
@@ -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 = @$"
<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
+12 -7
View File
@@ -3,24 +3,28 @@ using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.UI.Windows;
public class FrameHandler :
INavigationHandler<Frame>
public class ContentControlHandler(IViewModelContentBinder viewModelContentBinder) :
INavigationHandler<ContentControl>
{
public Task Handle(Navigate<Frame> args,
CancellationToken cancellationToken = default)
public Task Handle(Navigate<ContentControl> 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<Window>
{
public Task Handle(Navigate<Window> 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();