翼度科技»论坛 编程开发 .net 查看内容

学习.NET MAUI Blazor(三)、创建.NET MAUI Blazor应用并使用AntDesignBla

10

主题

10

帖子

30

积分

新手上路

Rank: 1

积分
30
大致了解了Blazor和MAUI之后,尝试创建一个.NET MAUI Blazor应用。
需要注意的是: 虽然都叫MAUI,但.NET MAUI与.NET MAUI Blazor 并不相同,MAUI还是以xaml为主,而MAUI Blazor则是以razor为主。
这个系列还是以MAUI Blazor为主,要创建一个MAUI Blazor应用,需要安装Visual Studio 2022 17.3 或更高版本,并在安装程序上,勾选.NET Multi-platform App UI 开发!最好是升级到最新的.NET 7。


目录

创建.NET MAUI Blazor应用

打开Visual Studio 2022,选择创建新项目

在搜索框输入MAUI,选择.NET MAUI Blazor应用,点下一步!

给项目起一个好听的名字,选择项目存在的位置,点下一步!

选择目标框架,这里选择的是.NET 7,点击创建。

等待创建项目及其依赖项还原。完成后的目录结构如下:

.NET MAUI Blazor 需要注意的地方

.NET MAUI Blazor 运行在WebView2上,WebView2是微软推出的新一代用于桌面端混合开发的解决方案。它可以让本地应用程序(WinForm、WPF、WinUI、Win32)、移动应用程序(MAUI)轻松嵌入Web技术。WebView2 控件使用 Microsoft Edge 作为呈现引擎在客户端应用程序及App中显示 Web 内容。使用 WebView2 可以将 Web 代码嵌入到客户端应用程序及App中的不同部分,或在单个 WebView 实例中构建所有本机应用程序。
可以这么看MAUI Blazor, .NET MAUI 包含 BlazorWebView 控件,该控件运行将 Razor 组件呈现到嵌入式 Web View 中。 通过结合使用 .NET MAUI 和 Blazor,可以跨移动设备、桌面设备和 Web 重复使用一组 Web UI 组件。
说人话就是,它就是一个Hybrid App(混合应用) !
调试.NET MAUI Blazor

在windows上调试 MAUI Blazor应用,需要Windows 10 1809及更高版本上,并打开开发者模式。
windows 11上,位于设置->隐私和安全性->开发者选项->开发人员模式


点击Windows Machine,运行程序!

如无意外,运行成功!

这时,MAUI Blazor使用的是bootstrap样式以及open-iconic图标。
在wwwroot/index.html中也可以看到
  1. [/code]现在已经有个很多基于Blazor的组件库,所以暂时把默认的bootstrap替换成第三方组件库,这里使用的是AntDesignBlazor。
  2. [size=6]使用AntDesignBlazor 组件库[/size]
  3. [size=5]安装依赖:[/size]
  4. [code]PM> NuGet\Install-Package AntDesign.ProLayout -Version 0.13.1
复制代码
注入AntDesign

在MauiProgram.cs注入AntDesign 服务与设置基本配置,完整的MauiProgram.cs代码
  1. using Microsoft.Extensions.Logging;
  2. using MauiBlazorApp.Data;
  3. namespace MauiBlazorApp;
  4. public static class MauiProgram
  5. {
  6.         public static MauiApp CreateMauiApp()
  7.         {
  8.                 var builder = MauiApp.CreateBuilder();
  9.                 builder
  10.                         .UseMauiApp<App>()
  11.                         .ConfigureFonts(fonts =>
  12.                         {
  13.                                 fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
  14.                         });
  15.                 builder.Services.AddMauiBlazorWebView();
  16. #if DEBUG
  17.                 builder.Services.AddBlazorWebViewDeveloperTools();
  18.                 builder.Logging.AddDebug();
  19. #endif
  20.                 builder.Services.AddSingleton<WeatherForecastService>();
  21.         //注入AntDesign
  22.         builder.Services.AddAntDesign();
  23.                 //基本配置
  24.                 builder.Services.Configure<ProSettings>(settings =>
  25.                 {
  26.             settings.NavTheme = "light";
  27.             settings.Layout = "side";
  28.             settings.ContentWidth = "Fluid";
  29.                         settings.FixedHeader = false;
  30.                         settings.FixSiderbar = true;
  31.             settings.Title = "DotNet宝藏库";
  32.                         settings.PrimaryColor = "daybreak";
  33.                         settings.ColorWeak = false;
  34.                         settings.SplitMenus= false;
  35.                         settings.HeaderRender= true;
  36.                         settings.FooterRender= false;
  37.                         settings.MenuRender= true;
  38.                         settings.MenuHeaderRender= true;
  39.                         settings.HeaderHeight = 48;
  40.                 });
  41.                 return builder.Build();
  42.         }
  43. }
复制代码
配置项都写上了。参数含义从表达的意思就能看出来,不做注释了!
引入样式

打开wwwroot/index.html。由于我们使用的是AntDesign,所以需要改造下index.html,修改后内容如下:
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="utf-8" />
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
  6.     <title>DotNet宝藏库</title>
  7.     <base href="/" />
  8.    
  9.     <link href="_content/AntDesign/css/ant-design-blazor.css" rel="stylesheet" />
  10.     <link rel="stylesheet" href="_content/AntDesign.ProLayout/css/ant-design-pro-layout-blazor.css" />
  11. </head>
  12. <body>
  13.    
  14.    
  15.         
  16.         
  17.             
  18.                
  19.                     
  20.                         <i ></i><i ></i><i ></i><i ></i>
  21.                     
  22.                
  23.             
  24.             
  25.                  
  26.             
  27.         
  28.    
  29.    
  30.    
  31.    
  32. </body>
  33. </html>
复制代码
加入命名空间

在_Imports.razor添加AntDesign命名空间:
  1. @using System.Net.Http
  2. @using Microsoft.AspNetCore.Components.Forms
  3. @using Microsoft.AspNetCore.Components.Routing
  4. @using Microsoft.AspNetCore.Components.Web
  5. @using Microsoft.AspNetCore.Components.Web.Virtualization
  6. @using Microsoft.JSInterop
  7. @using MauiBlazorApp
  8. @using MauiBlazorApp.Shared
  9. //引入AntDesign
  10. @using AntDesign
复制代码
设置容器

在Main.razor中加入
  1. <Router AppAssembly="@typeof(Main).Assembly">
  2.     <Found Context="routeData">
  3.         <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
  4.         <FocusOnNavigate RouteData="@routeData" Selector="h1" />
  5.     </Found>
  6.     <NotFound>
  7.         <LayoutView Layout="@typeof(MainLayout)">
  8.             <p role="alert">Sorry, there's nothing at this address.</p>
  9.         </LayoutView>
  10.     </NotFound>
  11. </Router>
  12. <AntContainer />
复制代码
修改 MainLayout


  • 修改MainLayout.razor。
  • 把MainLayout.razor中默认布局删除
  • 引入AntDesign.ProLayout
  • 设置布局为AntDesign.ProLayout
  • 构造菜单、页脚的链接、版权
  • wwwroot目录下新建个文件夹images,把提前准备好的logo放进去
完整代码如下:
  1. @using AntDesign.ProLayout
  2. @inherits LayoutComponentBase
  3. <AntDesign.ProLayout.BasicLayout
  4.     Logo="@("images/logo.png")"
  5.     MenuData="MenuData">
  6.     <ChildContent>
  7.         @Body
  8.     </ChildContent>
  9.     <FooterRender>
  10.         <FooterView Copyright="MauiBlazorApp" Links="Links"></FooterView>
  11.     </FooterRender>
  12. </AntDesign.ProLayout.BasicLayout>
  13. <SettingDrawer />
  14. @code
  15. {
  16.     private readonly MenuDataItem[] MenuData =
  17.         {
  18.         new MenuDataItem
  19.         {
  20.             Path = "/",
  21.             Name = "Home",
  22.             Key = "Home",
  23.             Icon = "home"
  24.         },
  25.         new MenuDataItem
  26.         {
  27.             Path = "/Counter",
  28.             Name = "Counter",
  29.             Key = "Counter",
  30.             Icon = "plus"
  31.         },
  32.         new MenuDataItem
  33.         {
  34.             Path = "/FetchData",
  35.             Name = "FetchData",
  36.             Key = "FetchData",
  37.             Icon = "cloud"
  38.         }
  39.     };
  40.     private readonly LinkItem[] Links =
  41.     {
  42.         new LinkItem
  43.         {
  44.             Key = "DotNet宝藏库",
  45.             Title = "基于Ant Design Blazor",
  46.             Href = "https://antblazor.com",
  47.             BlankTarget = true
  48.         }
  49.     };
  50. }
复制代码
这时可以把项目中无用的内容删除掉了,如Shared/NavMenu.razor、wwwroot/css文件。
由于删除掉了css文件夹,页面元素肯定没有样式了。那么就简单的改造下默认的几个页面!
改造默认页面

index.razor

打开Pages/Index.razor,将演示组件SurveyPrompt 删掉。顺便把Shared/SurveyPrompt.razor也删除掉。将Hello, world!


替换为Ant Design组件。
  1. @page "/"
  2. <Title Level="1">Hello,DotNet宝藏库</Title>
  3. <br />
  4. <Text Type="success">欢迎关注我的公众号!</Text>
复制代码
Counter.razor

打开 Pages/Counter.razor,将代码改为如下:
  1. @page "/counter"
  2. <Title Level="2">HCounter</Title>
  3. <p role="status">Current count: @currentCount</p>
  4. <Button @onclick="IncrementCount" Type="primary">AntDesign 按钮</Button>
  5. @code {
  6.     private int currentCount = 0;
  7.     private void IncrementCount()
  8.     {
  9.         currentCount++;
  10.     }
  11. }
复制代码
FetchData.razor

打开Pages/FetchData.razor,将数据表格替换为Ant Design,删除页面所有代码,替换为Ant Design的示例!
  1. @page "/fetchdata"
  2. @using System.ComponentModel
  3. @using AntDesign.TableModels
  4. @using System.Text.Json
  5. @using MauiBlazorApp.Data
  6. @inject WeatherForecastService ForecastService
  7. <Table @ref="table"
  8.        TItem="WeatherForecast"
  9.        DataSource="@forecasts"
  10.        Total="_total"
  11.        @bind-PageIndex="_pageIndex"
  12.        @bind-PageSize="_pageSize"
  13.        @bind-SelectedRows="selectedRows"
  14.        OnChange="OnChange">
  15.     <Selection Key="@(context.Id.ToString())" />
  16.     <PropertyColumn Property="c=>c.Id" Sortable />
  17.     <PropertyColumn Property="c=>c.Date" Format="yyyy-MM-dd" Sortable />
  18.     <PropertyColumn Property="c=>c.TemperatureC" Sortable />
  19.     <PropertyColumn Title="Temp. (F)" Property="c=>c.TemperatureF" />
  20.     <PropertyColumn Title="Hot" Property="c=>c.Hot">
  21.         <Switch @bind-Value="@context.Hot"></Switch>
  22.     </PropertyColumn>
  23.     <PropertyColumn Property="c=>c.Summary" Sortable />
  24.     <ActionColumn>
  25.         <Space>
  26.             <SpaceItem><Button Danger OnClick="()=>Delete(context.Id)">Delete</Button></SpaceItem>
  27.         </Space>
  28.     </ActionColumn>
  29. </Table>
  30. <br />
  31. <p>PageIndex: @_pageIndex | PageSize: @_pageSize | Total: @_total</p>
  32. <br />
  33. <h5>selections:</h5>
  34. @if (selectedRows != null && selectedRows.Any())
  35. {
  36.     <Button Danger Size="small" OnClick="@(e => { selectedRows = null; })">Clear</Button>
  37.     @foreach (var selected in selectedRows)
  38.     {
  39.         <Tag @key="selected.Id" Closable OnClose="e=>RemoveSelection(selected.Id)">@selected.Id - @selected.Summary</Tag>
  40.     }
  41. }
  42. <Button Type="@ButtonType.Primary" OnClick="()=> { _pageIndex--; }">Previous page</Button>
  43. <Button Type="@ButtonType.Primary" OnClick="()=> { _pageIndex++; }">Next Page</Button>
  44. @code {
  45.     private WeatherForecast[] forecasts;
  46.     IEnumerable<WeatherForecast> selectedRows;
  47.     ITable table;
  48.     int _pageIndex = 1;
  49.     int _pageSize = 10;
  50.     int _total = 0;
  51.     protected override async Task OnInitializedAsync()
  52.     {
  53.         forecasts = await GetForecastAsync(1, 50);
  54.         _total = 50;
  55.     }
  56.     public class WeatherForecast
  57.     {
  58.         public int Id { get; set; }
  59.         [DisplayName("Date")]
  60.         public DateTime? Date { get; set; }
  61.         [DisplayName("Temp. (C)")]
  62.         public int TemperatureC { get; set; }
  63.         [DisplayName("Summary")]
  64.         public string Summary { get; set; }
  65.         public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
  66.         public bool Hot { get; set; }
  67.     }
  68.     private static readonly string[] Summaries = new[]
  69.     {
  70.         "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
  71.     };
  72.     public void OnChange(QueryModel<WeatherForecast> queryModel)
  73.     {
  74.         Console.WriteLine(JsonSerializer.Serialize(queryModel));
  75.     }
  76.     public Task<WeatherForecast[]> GetForecastAsync(int pageIndex, int pageSize)
  77.     {
  78.         var rng = new Random();
  79.         return Task.FromResult(Enumerable.Range((pageIndex - 1) * pageSize + 1, pageSize).Select(index =>
  80.         {
  81.             var temperatureC = rng.Next(-20, 55);
  82.             return new WeatherForecast
  83.                 {
  84.                     Id = index,
  85.                     Date = DateTime.Now.AddDays(index),
  86.                     TemperatureC = temperatureC,
  87.                     Summary = Summaries[rng.Next(Summaries.Length)],
  88.                     Hot = temperatureC > 30,
  89.                 };
  90.         }).ToArray());
  91.     }
  92.     public void RemoveSelection(int id)
  93.     {
  94.         var selected = selectedRows.Where(x => x.Id != id);
  95.         selectedRows = selected;
  96.     }
  97.     private void Delete(int id)
  98.     {
  99.         forecasts = forecasts.Where(x => x.Id != id).ToArray();
  100.         _total = forecasts.Length;
  101.     }
  102. }
复制代码
运行效果:





总结

暂无,下次再会
欢迎大家关注我的微信公众号,一起进步,一起成长

来源:https://www.cnblogs.com/gmval/archive/2022/12/29/17013095.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具