MAUI Blazor 项目实战 - 从0到1轻松构建多平台应用UI
前言
最近在项目中尝鲜了MAUI,总体感受下来还是挺不错的,优缺点并存,但是瑕不掩瑜,目前随着.Net版本的迭代升级对它的支持也越来越友好,相信未来可期!感兴趣的朋友欢迎关注。文章中如有不妥的地方,也请多多指教。
项目效果图

什么是.NET MAUI?
网上关于MAUI介绍相关的内容也挺多的了,这里只做简单介绍。了解更多
.NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用。
使用 .NET MAUI,可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。

什么是Blazor Hybrid?
Blazor Hybrid(混合),可以通过它在 ASP.NET Core 应用中使用 .NET 生成交互式客户端 Web UI。
使用 Blazor Hybrid 将桌面和移动本机客户端框架与 .NET 和 Blazor 结合使用。
在 Blazor Hybrid 应用中,Razor 组件在设备上本机运行。 组件通过本地互操作通道呈现到嵌入式 Web View 控件。 组件不在浏览器中运行,并且不涉及 WebAssembly。 Razor 组件可快速加载和执行代码,组件可通过 .NET 平台完全访问设备的本机功能。
Blazor Hybrid 应用与MAUI
Blazor Hybrid 支持内置于 MAUI 框架 。.NET MAUI 包含 BlazorWebView 控件,该控件运行将 Razor 组件 呈现到嵌入式 Web View 中。 通过结合使用 .NET MAUI 和 Blazor,可以跨移动设备、桌面设备和 Web 重复使用一组 Web UI 组件。
项目准备
- .Net 7
- Visual Studio 2022
项目搭建
MultiPlatform.Blazor
MultiPlatform.Maui 
MultiPlatform.Server
整个项目结构如下:

项目整体思路就是将Blazor UI样式抽离至 MultiPlatform.Blazor(Razor类库)项目中,MultiPlatform.Maui(安卓、IOS等)项目用来构建多端应用,MultiPlatform.Server 则用来跑Web,可以方便我们调整样式。
1.抽离 MultiPlatform.Maui UI 至 MultiPlatform.Blazor

- 添加 MultiPlatform.Blazor 项目引用
- 文件抽离过去后注意调整命名空间,直接调整 MultiPlatform.Blazor 项目的 _Imports.razor即可。
@using Microsoft.AspNetCore.Components.Web
@using MultiPlatform.Blazor.Shared
@using Microsoft.AspNetCore.Components.Routing
@using MultiPlatform.Blazor.Data
- 因为我们将Main.razor文件抽离到了 MultiPlatform.Blazor,所以我们还需要调整 MultiPlatform.Maui项目中的 MainPage.xaml 文件:(相关知识点参考)
BlazorWebView 项目模板创建的 在 MainPage.xaml 中定义,并指向 Blazor 应用的根:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MultiPlatform.Maui"
x:Class="MultiPlatform.Maui.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<BlazorWebView x:Name="blazorWebView" HostPage="wwwroot/index.html">
<BlazorWebView.RootComponents>
<RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
</BlazorWebView.RootComponents>
</BlazorWebView>
</ContentPage>
应用的根 Razor 组件 位于 Main.razor 中,Razor 将其编译为应用程序根命名空间中名为 Main 的类型。 其余 Razor 组件位于页面和共享项目文件夹中,与默认 Blazor Web 模板中使用的组件相同。 应用的静态 Web 资产位于 wwwroot 文件夹中。
MainPage.xaml:
2.调整 MultiPlatform.Server项目
1.移除 MultiPlatform.Server的 MainLayout 文件
2.更改App.razor 文件,使用 AdditionalAssemblies 加载 MultiPlatform.Blazor 程序集
3.添加 MultiPlatform.Blazor 项目引用
最后项目结构调整如下:
到此,比较基础的多端应用就搭建完成了。
下面我们再试试应用一个Blazor框架到我们的项目中。
MASA Blazor MAUI
1.MultiPlatform.Blazor 项目安装 MASA Blazor Nuget包

Server 项目Program.cs文件与Maui项目的MauiProgram.cs文件中注册相关服务
builder.Services.AddMasaBlazor();
2.MultiPlatform.Server 项目 _Host.cshtml 文件与MultiPlatform.Maui 项目的wwwroot/index.html引入样式、字体、脚本
<link href="_content/Masa.Blazor/css/masa-blazor.css" rel="stylesheet">
<link href="_content/Masa.Blazor/css/masa-extend-blazor.css" rel="stylesheet">
<link href="https://cdn.masastack.com/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.masastack.com/npm/materialicons/materialicons.css" rel="stylesheet">
<link href="https://cdn.masastack.com/npm/fontawesome/v5.0.13/css/all.css" rel="stylesheet">
<script src="_content/BlazorComponent/js/blazor-component.js"></script>
示例:
注:如果这里嫌麻烦也可以选用模板安装
模板使用示例,具体请移步 [开始使用MASA Blazor]
(https://docs.masastack.com/blazor/getting-started/installation#section-81ea52a85b8988c5)
//安装 Masa.Template 模板(目前1.0还没发正式版,所以是Masa.Template::1.0.0-rc.1,但不影响使用)
dotnet new install Masa.Template::1.0.0-rc.1
//创建masablazor-maui 模板
dotnet new masablazor-maui -o MauiApp

3.替换 MultiPlatform.Blazor 项目的Shared/MainLayout文件代码
这里使用MASA Blazor框架中的 App bars(应用栏)组件与 Navigation drawers(导航抽屉)组件替换了原来的bootstrap样式
@inherits LayoutComponentBase
<MApp>
<MAppBar App Elevation="2">
<MAppBarNavIcon @onclick="() => _drawer = !_drawer"></MAppBarNavIcon>
<MToolbarTitle>CrossPlatformApp</MToolbarTitle>
<MSpacer></MSpacer>
<MButton Text Color="primary" Target="_blank" Href="https://docs.masastack.com/blazor/introduction/why-masa-blazor">About</MButton>
</MAppBar>
<MNavigationDrawer App @bind-Value="_drawer">
<MList Nav Routable>
<MListItem Href="/" ActiveClass="primary--text">
<MListItemIcon>
<MIcon>mdi-home</MIcon>
</MListItemIcon>
<MListItemContent>
<MListItemTitle>Home</MListItemTitle>
</MListItemContent>
</MListItem>
<MListItem Href="/counter" ActiveClass="primary--text">
<MListItemIcon>
<MIcon>mdi-plus</MIcon>
</MListItemIcon>
<MListItemContent>
<MListItemTitle>Counter</MListItemTitle>
</MListItemContent>
</MListItem>
<MListItem Href="/fetchdata" ActiveClass="primary--text">
<MListItemIcon>
<MIcon>mdi-list-box</MIcon>
</MListItemIcon>
<MListItemContent>
<MListItemTitle>Fetch data</MListItemTitle>
</MListItemContent>
</MListItem>
</MList>
</MNavigationDrawer>
<MMain>
<MContainer Fluid>
<MErrorHandler>
@Body
</MErrorHandler>
</MContainer>
</MMain>
</MApp>
@code {
private bool _drawer;
}
4.更改 MultiPlatform.Blazor 服务的 Pages/Index.razor 文件代码
增加 Bottom navigation (底部导航栏) 组件
@page "/"
<Container>
<MRow>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
<MBottomNavigation @bind-Value="value"
Color="teal"
Fixed
Style="display:flex"
Grow>
<MButton>
<span>Recents</span>
<MIcon>mdi-history</MIcon>
</MButton>
<MButton>
<span>Favorites</span>
<MIcon>mdi-heart</MIcon>
</MButton>
<MButton>
<span>Nearby</span>
<MIcon>mdi-map-marker</MIcon>
</MButton>
</MBottomNavigation>
</MRow>
</Container>
@code {
StringNumber value = 1;
}
看看效果:
到此,基本上大功告成了。
结尾
文章中的示例比较基础,基本上直接cv过去就可以用,还是比较适合新手朋友上手的。
最后由于文章篇幅有限,对MAUI与Blazor感兴趣的朋友可自行深入研究。
后续系列文章都会基于这个Demo项目进行分享,欢迎关注。
源码地址
https://github.com/fengzhonghao8-24/MultiPlatformApp
MAUI Blazor 项目实战 - 从0到1轻松构建多平台应用UI的更多相关文章
- 从零构建以太坊(Ethereum)智能合约到项目实战——第23章 从零构建和部署去中心化投票App,decentralization Voting Dapp
P90 .1-从零构建和部署去中心化投票App-01 P91 .2-从零构建和部署去中心化投票App-02 P92 .3-从零构建和部署去中心化投票App-03 参考博文:http://liyuech ...
- Blazor Hybrid / MAUI 简介和实战
1. Blazor Blazor 是一个使用 .NET 生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建信息丰富的交互式 UI. 共享使用 .NET 编写的服务 ...
- Bootstrap Blazor Viewer 图片浏览器 组件更新, 支持流转图片(ImageFromStream), 用于本地项目例如 MAUI Blazor,Blazor hybrid
示例: https://blazor.app1.es/viewer 使用方法: 1.nuget包 BootstrapBlazor.Viewer 2._Imports.razor 文件 或者页面添加 添 ...
- [MAUI 项目实战] 手势控制音乐播放器(一): 概述与架构
这是一篇系列博文.请关注我,学习更多.NET MAUI开发知识! [MAUI 项目实战] 手势控制音乐播放器(一): 概述与架构 [MAUI 项目实战] 手势控制音乐播放器(二): 手势交互 [MAU ...
- Asp.Net Core 项目实战之权限管理系统(0) 无中生有
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- Net Core 项目实战之权限管理系统(0)
0 前言 Net Core 项目实战之权限管理系统(0) 无中生有 0 http://www.cnblogs.com/fonour/p/5848933.html 学习的最好方法就是动手去做,这里以 ...
- Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录
1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...
- Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级
1.权限管理 权限管理的基本定义:百度百科. 基于<Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员.后台管理员同时登录>我们做过了登录认证, ...
- Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例
本文目录 1. Net下日志记录 2. NLog的使用 2.1 添加nuget引用NLog.Web.AspNetCore 2.2 配置文件设置 2.3 依赖配置及调用 ...
- Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类
本文目录 1. 前沿 2.CacheHelper基于Microsoft.Extensions.Caching.Memory封装 3.XmlHelper快速操作xml文档 4.Serializatio ...
随机推荐
- 一些随笔 No.2
数据库 单表VS多表联合 多表联合查询的优势区域在于敏捷开发,主要用于过于庞大却可拆分的储存需求 但是劣势也很明显:更多的查询约束条件会用掉数据库服务器额外的cpu/内存/io,也不方便更未来的分布式 ...
- Spring 源码阅读之标签解析
全局目录.md 引子 1.容器最基本使用.md 系列1 - bean 标签解析: 2.XmlBeanFactory 的类图介绍.md 3.XmlBeanFactory 对xml文件读取.md 4.xm ...
- sms-activate操作简便易上手且好用的接码工具【保姆级教程】
前言 有些国外应用在使用应用上的功能时需要注册账号,由于某种不可抗因素,我们的手机号一般不支持注册,接收不到信息验证码,于是我们可以使用SmS-Activate提供的服务,使用$实现我们的需求(大概一 ...
- spring-boot-starter-parent not found
项目开始的springboot版本为2.6.6 <parent> <groupId>org.springframework.boot</groupId> <a ...
- YII2.0的文件上传, 并把文件名称重新编译
/** *@Action 文件上传示例 *@这里我们演示的是一个YII2.0的文件上传, 并把文件名称重新编译 *@我们上传的是一个叫 photo 的jpg和png格式的文件 */ Controlle ...
- Yii framework 应用小窍门
Yii framework 应用小窍门 1. Yii Framework] 如何获取当前controller的名称? 下面语句就可以获取当前控制器的名称了! Php代码 Yii::app ...
- Java学习笔记03
1. 流程控制语句 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.所以,我们必须清楚每条语句的执行流程.而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能. 1.1 分 ...
- js计算当前时间差
1 function timesFun(timesData) { 2 //如果时间格式是正确的,那下面这一步转化时间格式就可以不用了 3 var dateBegin = new Date(timesD ...
- RocketMQ消费者是如何负载均衡的
摘要:RocketMQ 支持两种消息模式:集群消费( Clustering )和广播消费( Broadcasting ). 本文分享自华为云社区<一文讲透RocketMQ消费者是如何负载均衡的& ...
- Git&GitHub简介与入手(一)
一.Git版本控制 1.集中式版本控制工具:SVN(版本控制集中在服务器端,会有单点故障风险): 2.分布式版本控制工具:Git: 3.Git简史 Talk is cheap, show me the ...
