MAUI库推荐二:MPowerKit

项目介绍

MPowerKit 是.NET MAUI 的导航框架。

项目支持常规/模式导航,打开/关闭窗口,多窗口、区域导航和弹出窗口。

项目灵感来自于Prism项目,Prism对MAUI的支持不是很友好。因此作者开发了针对MAUI的导航框架。提供了与Prism相同的MAUI应用程序导航原则,但实现方式完全不同。性能也略有提高。带来了正确的方式处理所有平台相同行为的系统返回按钮功能。

项目地址

github.com/MPowerKit/N...

相关接口介绍

MPowerKit.Navigation.Core 核心库的相关接口

  • IInitializeAware 只有一个void Initialize(INavigationParameters parameters);方法,这个方法在页面和它的视图模型创建后立即执行,并且没有附加到可视化树。在该页的生存期内仅执行一次。如果你想让页面或者视图模型知道这个事件,必须实现这个接口。
  • IDestructible 只实现void Desctroy();,从可视化树中分离出来并且在GC之后立即实行。按倒序连续的对导航堆栈中的每隔页面执行。在页面生存期内仅执行一次。如果你想让页面或者视图模型知道这个事件,必须实现这个接口。
  • INavigationAware 此接口实现了两个方法
    • void OnNavigatedFrom(INavigationParameters parameters); 返回上层页面时调用。
    • void OnNavigatedTo(INavigationParameters parameters); 进入当前页面时调用。
  • IPageLifecycleAware 该接口绑定到Page类的生命周期事件。有两个接口方法:
    • void OnAppearing(); 当页面出现时执行。
    • void OnDisappearing(); 当页面消失时执行。
  • IWindowLifecycleAware 与Window类的生命周期事件绑定,有两个方法:void OnResume();void OnSleep();
  • ISystemBackButtonClickAware 如果想要完全控制导航功能,需要在Page或者ViewModel中实现这个接口。只有一个方法:bool OnSystemBackButtonClick();。 此方法在单击系统返回按钮时执行,可在MAUI支持的所有平台上有效。返回值表示是否处理此事件。如果处理了,那么向后导航应该有开发人员处理。如果没有,在向后导航将由MAUI本身处理。
  • IActiveTabAware 这个接口只有一个方法:bool IsOnActiveTab { get; set; }。用于表示页面是否在活动状态
  • IFlyoutPageFlyoutPresentedAware

使用方法

使用时在项目中引用对应的nuget包即可。可搜索MPowerKit,找到对应相关库即可。

  • MPowerKit.Navigation 导航功能
  • MPowerKit.Regions 区域功能
  • MPowerKit.Navigation.Popups 弹出功能

根据自己的需要添加相关库即可。

MPowerKit.Navigation

此库提供了必要的基础功能,并以完全MVVM的方式构建了丰富的应用程序,提供了不同页面之间的导航。

需要在MauiProgram中添加如下代码:

ini 复制代码
builder
    .UseMauiApp<App>()
    .UseMPowerKitNavigation(mpowerBuilder =>
    {
        mpowerBuilder.ConfigureServices(s =>
        {
            s.RegisterForNavigation<MainPage>();
        })
        .OnAppStart("NavigationPage/MainPage");
    });

启动应用程序时,以MainPage作为根页面启动。如果想要注册服务你可以在ConfigureServices中添加代码。在此库中已添加了必要的一下服务。如果你想进行扩展可以自己更改相关功能:

  • MPowerKitWindow 注册为瞬态服务IMPowerKitWindow,并提供处理系统返回按钮和窗口生命周期的能力,如果需要更改MPowerKitWindow的实现或者改变西的后退按钮点击行为,可以扩展这个类并注册新的实现。
ini 复制代码
mpowerBuilder.ConfigureServices(s =>
{
    s.AddTransient<IMPowerKitWindow, NewWindowThatExtendsMPowerKitWindow>();
});
  • NavigationService 作为作用域服务注册,应用程序导航,如果需要覆盖它的一些基本实现,可以使用你的实现并使用如下注册:
ini 复制代码
mpowerBuilder.ConfigureServices(s =>
{
    s.AddScoped<INavigationService, YourNavigationService>();
});

注册页面

方法一:

csharp 复制代码
mpowerBuilder.ConfigureServices(s =>
{
    s.RegisterForNavigation<MainPage>();  //解析为`nameof`,没有指定视图模型,这意味着将BindingContext设置为new object
})

方法二:

csharp 复制代码
mpowerBuilder.ConfigureServices(s =>
{
    s.RegisterForNavigation<MainPage, MainPageViewModel>();//解析为`nameof`,并指定view model为`MainPageViewModel`
})

方法三:

csharp 复制代码
mpowerBuilder.ConfigureServices(s =>
{
    s.RegisterForNavigation<MainPage, MainPageViewModel>("TheAssociationNameForYourPage");//解析为关联名称,这是首选方式,并指定view model为`MainPageViewModel`
})

已注册页面

  • NavigationPage
  • TabNavigationPage
  • TabbedPage
  • FlyoutPage

注册自己的行为

如果需要使用已经附加的行为来解析页面,可以实现如下代码:

ini 复制代码
mpowerBuilder.ConfigureServices(s =>
{
    // Register behaviors
    s.RegisterBehavior<Page, SomeUsefulBehaviorYouWantToAttachToEachPageInYourApp>();
    s.RegisterBehavior<SecondPage, SomeUsefulBehaviorYouWantToAttachOnlyToSecondPage>();
})

已存在的行为

  • PageLifecycleAwareBehavior 负责处理页面的OnAppearing() 和OnDisappearing()事件,在应用中所有页面中已注册。
  • TabbedPageActiveTabAwareBehavior 负责处理TabbedPageCurrentPageChanged事件。
  • FlyoutPageFlyoutPresentedAwareBehavior 负责处理FlyoutPageIsPresentedChanged 事件

配置应用启动

大多数情况下,使用下面的设置足以在所需要页面启动应用程序。

arduino 复制代码
mpowerBuilder.OnAppStart("NavigationPage/YourPage");

如果需要一些初始化的工作,可使用如下方法:

  • OnInitialized()
javascript 复制代码
//方法一(无参):
mpowerBuilder.OnInitialized(() =>
{
    //your initializations
});
//方法二(带参)
mpowerBuilder.OnInitialized(serviceProvider =>
{
    //your initializations
});
  • OnAppStart 当应用程序准备好导航到第一页面时执行,这是必须的,如果没有它,应用程序在开始就会崩溃。
arduino 复制代码
mpowerBuilder.OnAppStart("NavigationPage/YourPage");

如果想在导航前执行一些异步方法,可用如下代码,提供一个登录功能。

dart 复制代码
mpowerBuilder.OnAppStart(async (serviceProvider, navigationService) =>
{
    if (await IsUserLoggedIn())
    {
        await navigationService.NavigateAsync("NaviationPage/MainPage");
    }
    else await navigationService.NavigateAsync("LoginPage");
});

使用

要在应用中使用导航,你需要将INavigationService注入到你的页面或者视图的构造函数中,然后就可以导航到想要的页面

csharp 复制代码
INavigationService _navigationService;

await _navigationService.NavigateAsync("YourPageAssociationName", optionalNavigationParameters, optionalIsModal, optionalIsAnimated);

每个页面或者VM都有自己的INavigationService实例,它被注册为作用域服务。 导航到页面:

csharp 复制代码
ValueTask<NavigationResult> NavigateAsync(string uri, INavigationParameters? navigationParameters = null, bool modal = false, bool animated = true);

返回

要会到上一页或者根页,可以冲任何页面或者VM中执行此操作。

csharp 复制代码
ValueTask<NavigationResult> GoBackAsync(INavigationParameters? parameters = null, bool modal = false, bool animated = true);
ValueTask<NavigationResult> GoBackToRootAsync(INavigationParameters? parameters = null, bool animated = true);

打开新窗口或者关闭窗口

csharp 复制代码
ValueTask<NavigationResult> OpenNewWindowAsync(string uri, INavigationParameters? parameters = null);
ini 复制代码
NavigationResult CloseWindow(Guid? windowId = null);

MPowerKit.Navigation.Popups

弹窗功能这个库基于 MPowerKit.NavigationMPowerKit.Popups

使用UsePopupNavigation()进行引用,如下所示:

ini 复制代码
builder
    .UseMauiApp<App>()
    .UseMPowerKitNavigation(mpowerBuilder =>
    {
        mpowerBuilder.ConfigureServices(s =>
        {
            s.RegisterForNavigation<MainPage>();
            s.RegisterForNavigation<TestPopupPage>();
        })
        .UsePopupNavigation()
        .OnAppStart("NavigationPage/MainPage");
    });

注册Popup页面可参考注册页面

每一个弹出页面,必须集成库MPowerKit.Popups中的PopupPage

可通过在构造函数中注册接口IPopupDialogAware实现弹窗功能,可进行参数传递和关闭功能。如下示例所示:

csharp 复制代码
public class TestPopupViewModel : IPopupDialogAware
{
    public Action<(Confirmation Confirmation, bool Animated)> RequestClose { get; set; }

    protected virtual async Task Cancel(object obj = null)
    {
        var nparams = new NavigationParameters
        {
            { NavigationConstants.CloseParameter, obj }
        };

        RequestClose?.Invoke((new Confirmation(false, nparams), true));
    }

    protected virtual async Task Confirm(object obj = null)
    {
        var nparams = new NavigationParameters
        {
            { NavigationConstants.CloseParameter, obj }
        };

        RequestClose?.Invoke((new Confirmation(true, nparams), true));
    }
}

MPowerKit.Navigation.Regions

与Prism的导航功能相似,但是实现方式不同。

添加UseMPowerKitRegions() 到MauiProgram.cs文件中:

scss 复制代码
builder
    .UseMauiApp<App>()
    .UseMPowerKitRegions();
ini 复制代码
builder
    .UseMauiApp<App>()
    .UseMPowerKitNavigation(mpowerBuilder =>
    {
        mpowerBuilder.ConfigureServices(s =>
        {
            s.RegisterForNavigation<MainPage>();
            s.RegisterForNavigation<RegionView1>();
        })
        .OnAppStart("NavigationPage/MainPage");
    })
    .UseMPowerKitRegions();

如果你将区域与MPowerKit.Navigation结合使用,你可以指定是否想要你的区域视图获得父页面的事件,如导航、销毁、生命周期等,只需要将UsePageEventsInRegions()到你代码中。

csharp 复制代码
builder
    .UseMauiApp<App>()
    .UseMPowerKitNavigation(mpowerBuilder =>
    {
        mpowerBuilder.ConfigureServices(s =>
        {
            s.RegisterForNavigation<MainPage>();
            s.RegisterForNavigation<RegionView1>();
        })
        .UsePageEventsInRegions()//此行代码
        .OnAppStart("NavigationPage/MainPage");
    })
    .UseMPowerKitRegions();

注册region页面可参考注册页面

使用

每个区域应该有一个父容器,类型为ContentView

csharp 复制代码
添加命名空间:
xmlns:regions="clr-namespace:MPowerKit.Regions;assembly=MPowerKit.Regions"
//添加一个简单的区域
<ContentView regions:RegionManager.RegionName="YourVeryMeaningfulRegionName" />

//与Prism不同,它可以有一个动态名称,如下所示
<ContentView regions:RegionManager.RegionName="{Binding DynamicString}" />

注意:区域名称必须为唯一的,否则应用会崩溃。

  • IRegionManager 将此接口注入到页面或者VM的构造函数中,使用方法
arduino 复制代码
IRegionManager _regionManager;

_regionManger.NavigateTo("YourRegionName", "RegionViewAssociationName", optionalNavigationParametersObject);

此文已在公众号:MAUI与Avalonia开启原创,欢迎关注与转载。

以往精品

1、MAUI库推荐一:MAUIIcons项目介绍 MAUIIcons是对Maui可用的Icon集合库。可以方便的在Maui上 - 掘金

相关推荐
风的归宿552 小时前
进程调度:深入Linux内核架构读书笔记
后端
代码扳手2 小时前
Go 微服务数据库实现全解析:读写分离、缓存防护与生产级优化实战
数据库·后端·go
Charlie_Byte2 小时前
Netty + Sa-Token 实现 WebSocket 握手认证
java·后端
多云的夏天2 小时前
SpringBoot3+Vue3基础框架(1)-springboot+对接数据库表登录
数据库·spring boot·后端
shoubepatien3 小时前
JAVA -- 12
java·后端·intellij-idea
木木一直在哭泣3 小时前
Spring 里的过滤器(Filter)和拦截器(Interceptor)到底啥区别?
后端
源码获取_wx:Fegn08953 小时前
基于springboot + vue物业管理系统
java·开发语言·vue.js·spring boot·后端·spring·课程设计
無量3 小时前
MySQL事务与锁机制深度剖析
后端·mysql
無量3 小时前
MySQL索引设计与优化实战
后端·mysql