从零搭建Maui框架,基于Prism9.0
Prism9.0正式版发布了,利用Prism搭建一个Maui框架。
一、用VS模板创建Maui项目
使用Visual Studio 2022及以上,创建.NET MAUI应用

二、 导包
导入Prism.Maui
和Prism.DryIoc.Maui
两个Nuget包

三、修改Maui程序入口
在MauiProgram.cs
中CreateMauiApp
方法中添加以下代码
1 2 3 4 5 6 7 8
| builder.UsePrism(prism => { prism.RegisterTypes(container => { container.RegisterForNavigation<MainPage>(); }); prism.CreateWindow(navigationService => navigationService.NavigateAsync($"/{nameof(MainPage)}")); });
|
上面代码的作用是,注册MainPage
到Prism的导航服务中。如果不注册,直接使用prism.CreateWindow
方法会报错,提示创建Root页面失败。
四、删除AppShell
使用Prism不需要AppShell
,这里直接删除。
在App.xaml
文件中删除 MainPage = new AppShell();
代码。
直接运行程序,会发现程序的行为和VS模板创建的动作行为基本是一致的。
这里因为我们删除了AppShell,所以看不到Home字样。
五、添加区域Region
- 将
MainPage.xaml
中的UI代码删除,新增ContentView
控件
- 导入命名空间
xmlns:prism="http://prismlibrary.com"
- 给
ContentView
附加区域导航属性prism:RegionManager.RegionName="MainRegion"
- 注释
MainPage.xaml.cs
中报错的部分
MainPage.xaml
完整代码如下
1 2 3 4 5 6 7 8 9 10 11
| <ContentPage x:Class="MauiPrism9Demo.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:core="clr-namespace:Core;assembly=Core" xmlns:prism="http://prismlibrary.com">
<ContentView prism:RegionManager.RegionName="MainRegion" />
</ContentPage>
|
六、添加新视图
新增Views文件夹和ViewModels文件夹。
在Views文件夹中新增一个名为ViewA
的.NET MAUI ContentView(XAML)
项目
在ViewModels中新增名为ViewAViewModel
的类,并使类继承Prism的MVVM基类BindableBase

七、注入新视图并导航
在程序入口处使用Prism基于区域注册新的视图。
代码为container.RegisterForRegionNavigation<ViewA, ViewAViewModel>();
新增Prism加载完成后导航到ViewA的代码。
1 2 3 4 5
| prism.OnInitialized((container) => { var regionManager = container.Resolve<IRegionManager>(); regionManager.RegisterViewWithRegion("MainRegion", "ViewA"); });
|
上面这段代码是在Prism初始化完成以后,使用区域管理器RegionManager
将ViewA
导航到MainRegion
中。
运行程序,会发现ViewA的UI已经显示在了应用程序中。
八、区域导航
重复第六条,新增ViewB和ViewBViewModel。
在ViewB中添加一个按钮,绑定命令为ToViewACommand。
1 2 3 4
| <Button Command="{Binding ToViewACommand}" HorizontalOptions="Center" Text="GoBack" VerticalOptions="Center" />
|
在ViewBViewModel中新增一个返回值为ICommand
的方法,代码如下
1 2 3 4
| public ICommand ToViewACommand => new DelegateCommand(() => { regionManager.RequestNavigate("MainRegion", nameof(ViewA)); });
|
同样在ViewA和ViewAViewModel中新增ToViewB的按钮和Command。
九、注册区域导航
在程序入口文件MauiProgram
中,像注册ViewA一样,新增ViewB和ViewBViewModel的注册,基于区域导航,
代码为container.RegisterForRegionNavigation<ViewB, ViewBViewModel>();
运行程序,ViewA和ViewB正常互相导航,基本框架完成。
十、完整代码
MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| namespace MauiPrism9Demo { public static class MauiProgram { public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder.UseMauiApp<App>();
builder.ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); });
builder.UsePrism(prism => { prism.RegisterTypes(container => { container.RegisterForNavigation<MainPage>(); container.RegisterForRegionNavigation<ViewA, ViewAViewModel>(); container.RegisterForRegionNavigation<ViewB, ViewBViewModel>(); }); prism.OnInitialized((container) => { var regionManager = container.Resolve<IRegionManager>(); regionManager.RegisterViewWithRegion("MainRegion", nameof(ViewA)); }); prism.CreateWindow(navigationService => navigationService.NavigateAsync($"/{nameof(MainPage)}")); });
#if DEBUG builder.Logging.AddDebug(); #endif
return builder.Build(); } } }
|
ViewA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?xml version="1.0" encoding="utf-8" ?> <ContentView x:Class="MauiPrism9Demo.Views.ViewA" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center"> <Label HorizontalOptions="Center" Text="ViewA" VerticalOptions="Center" /> <Button Command="{Binding ToViewBCommand}" HorizontalOptions="Center" Text="ToViewBCommand" VerticalOptions="Center" /> </VerticalStackLayout> </ContentView>
|
ViewAViewModel
1 2 3 4 5 6 7 8 9 10
| namespace MauiPrism9Demo.ViewModels { public class ViewAViewModel(IRegionManager regionManager) : BindableBase { public ICommand ToViewBCommand => new DelegateCommand(() => { regionManager.RequestNavigate("MainRegion", nameof(ViewB)); }); } }
|
十一、模块化
Prism.Maui的模块化和Prism.Wpf的模块化几乎是一样的。只需要在程序入口(MauiProgram
)处注册模块即可。
1 2 3 4 5
| prism.ConfigureModuleCatalog(configureCatalog => { configureCatalog.AddModule<CoreModule>() configureCatalog.AddModule<UiModule>() })
|
上面的代码添加了2个模块到应用程序中。模块只需要实现IModule
接口即可。
我这里把ViewA、ViewB包括ViewModel都移动到了UiModule中,注册视图(ViewA、ViewB)的代码都移动到了UiModule中。CoreModule是一些业务代码。
Ui移动到别的模块中以后,MauiProgram
中就可以将视图的注册和程序初始化导航都移除了。最终的MauiProgram
代码为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| namespace MauiPrism9Demo { public static class MauiProgram { public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder.UseMauiApp<App>();
builder.ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); });
builder.UsePrism(prism => { prism.RegisterTypes(container => { container.RegisterForNavigation<MainPage>(); });
prism.ConfigureModuleCatalog(configureCatalog => { configureCatalog.AddModule<CoreModule>(); configureCatalog.AddModule<UiModule>(); });
prism.CreateWindow(navigationService => navigationService.NavigateAsync($"/{nameof(MainPage)}")); });
#if DEBUG builder.Logging.AddDebug(); #endif
return builder.Build(); } } }
|
自此,整个基础框架就搭建完成了。