简单

导航

注册

public static class DependencyInjectionExtensions
{
    public static IHostBuilder ConfigureViews(this IHostBuilder hostBuilder)
    {
        return hostBuilder.ConfigureServices(
            (sc) =>
            {
                sc.AddSingleton<MainWindow>();
                sc.AddSingleton<MainViewModel>();

                // navigation
                sc.AddForNavigation(typeof(VisibilityView), typeof(VisibilityViewModel));
                sc.AddForNavigation(typeof(GridSplitterView), typeof(GridSplitterViewModel));
                sc.AddForNavigation(typeof(CustomizedTabItemView), typeof(CustomizedTabItemViewModel));
                sc.AddForNavigation(typeof(MessageBoxView), typeof(MessageBoxViewModel));
                sc.AddForNavigation(typeof(DragDropView), typeof(DragDropViewModel));
                sc.AddForNavigation(typeof(ProgressMaskView), typeof(ProgressMaskViewModel));
                sc.AddForNavigation(typeof(DesignTimeDataView), typeof(DesignTimeDataViewModel));
                sc.AddForNavigation(typeof(ValidationView), typeof(ValidationViewModel));
                sc.AddForNavigation(typeof(PlayerView), typeof(PlayerViewModel));
            }
        );
    }

    public static void AddForNavigation(this IServiceCollection sc, Type view, Type viewModel)
    {
        var viewItem = new ViewRegistryItem()
        {
            Name = view.Name,
            ViewType = view,
            ViewModelType = viewModel
        };

        sc.AddSingleton(viewItem);

        sc.AddTransient(view);
        sc.AddTransient(viewModel);
    }
}

发出导航请求

partial void OnSelectedViewChanged(ViewItem? value)
{
    if (value is null)
    {
        return;
    }

    Messenger.Send(value.ViewName, Channels.NAVIGATION);
}

处理导航请求

private void Navigate(string viewName)
{
    var views = this.serviceProvider.GetService<IEnumerable<ViewRegistryItem>>();
    var viewItem = views?.LastOrDefault(v => v.Name == viewName);
    if (viewItem is null)
    {
        return;
    }

    var view = this.serviceProvider.GetService(viewItem.ViewType);
    if (view is null)
    {
        return;
    }

    ContentView = view;
}

总结

Ref

Github: orrest/Tests