小秦哥 发表于 2022-12-29 20:10:15

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

大致了解了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。
https://img-blog.csdnimg.cn/f862b524f13b4dd49f84402fd66c21d7.png#pic_center

目录

[*]创建.NET MAUI Blazor应用
[*].NET MAUI Blazor 需要注意的地方
[*]调试.NET MAUI Blazor
[*]使用AntDesignBlazor 组件库

[*]安装依赖:
[*]注入AntDesign
[*]引入样式
[*]加入命名空间
[*]设置容器
[*]修改 MainLayout
[*]改造默认页面

[*]index.razor
[*]Counter.razor
[*]FetchData.razor


[*]运行效果:
[*]总结

创建.NET MAUI Blazor应用

打开Visual Studio 2022,选择创建新项目
https://img-blog.csdnimg.cn/0eca0d18a0024ca5b972873265bab7d5.png#pic_center
在搜索框输入MAUI,选择.NET MAUI Blazor应用,点下一步!
https://img-blog.csdnimg.cn/6b778ef14d164145a957d102a888b845.png#pic_center
给项目起一个好听的名字,选择项目存在的位置,点下一步!
https://img-blog.csdnimg.cn/c2e2b711c79946248a15e3b232beab75.png#pic_center
选择目标框架,这里选择的是.NET 7,点击创建。
https://img-blog.csdnimg.cn/8304dbad6f3e4c5c8729948513a9d500.png#pic_center
等待创建项目及其依赖项还原。完成后的目录结构如下:
https://img-blog.csdnimg.cn/03e83b2d26e94d2b82a7aa63481ad4a9.png#pic_center
.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上,位于设置->隐私和安全性->开发者选项->开发人员模式
https://img-blog.csdnimg.cn/4deb78f3ffd142c9b76d74f8028be565.png#pic_center
https://img-blog.csdnimg.cn/a9fd893726444dd5b5fd9c7e883938e6.png#pic_center
点击Windows Machine,运行程序!
https://img-blog.csdnimg.cn/aace09bb2b2c44fa8b1ce563d60043b3.png#pic_center
如无意外,运行成功!
https://img-blog.csdnimg.cn/e518d975aeeb4724af12ac53b3dc2a96.png#pic_center
这时,MAUI Blazor使用的是bootstrap样式以及open-iconic图标。
在wwwroot/index.html中也可以看到
现在已经有个很多基于Blazor的组件库,所以暂时把默认的bootstrap替换成第三方组件库,这里使用的是AntDesignBlazor。
使用AntDesignBlazor 组件库

安装依赖:

PM> NuGet\Install-Package AntDesign.ProLayout -Version 0.13.1注入AntDesign

在MauiProgram.cs注入AntDesign 服务与设置基本配置,完整的MauiProgram.cs代码
using Microsoft.Extensions.Logging;
using MauiBlazorApp.Data;

namespace MauiBlazorApp;

public static class MauiProgram
{
        public static MauiApp CreateMauiApp()
        {
                var builder = MauiApp.CreateBuilder();
                builder
                        .UseMauiApp<App>()
                        .ConfigureFonts(fonts =>
                        {
                                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                        });

                builder.Services.AddMauiBlazorWebView();

#if DEBUG
                builder.Services.AddBlazorWebViewDeveloperTools();
                builder.Logging.AddDebug();
#endif

                builder.Services.AddSingleton<WeatherForecastService>();
      //注入AntDesign
      builder.Services.AddAntDesign();
                //基本配置
                builder.Services.Configure<ProSettings>(settings =>
                {
            settings.NavTheme = "light";
            settings.Layout = "side";
            settings.ContentWidth = "Fluid";
                        settings.FixedHeader = false;
                        settings.FixSiderbar = true;
            settings.Title = "DotNet宝藏库";
                        settings.PrimaryColor = "daybreak";
                        settings.ColorWeak = false;
                        settings.SplitMenus= false;
                        settings.HeaderRender= true;
                        settings.FooterRender= false;
                        settings.MenuRender= true;
                        settings.MenuHeaderRender= true;
                        settings.HeaderHeight = 48;

                });
                return builder.Build();
        }
}配置项都写上了。参数含义从表达的意思就能看出来,不做注释了!
引入样式

打开wwwroot/index.html。由于我们使用的是AntDesign,所以需要改造下index.html,修改后内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
    <title>DotNet宝藏库</title>
    <base href="/" />
   
    <link href="_content/AntDesign/css/ant-design-blazor.css" rel="stylesheet" />
    <link rel="stylesheet" href="_content/AntDesign.ProLayout/css/ant-design-pro-layout-blazor.css" />
</head>

<body>

   

   
      
      
            
               
                  
                        <i ></i><i ></i><i ></i><i ></i>
                  
               
            
            
               
            
      
   

   

   
   
</body>

</html>加入命名空间

在_Imports.razor添加AntDesign命名空间:
@using System.Net.Http
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using MauiBlazorApp
@using MauiBlazorApp.Shared
//引入AntDesign
@using AntDesign设置容器

在Main.razor中加入
<Router AppAssembly="@typeof(Main).Assembly">
    <Found Context="routeData">
      <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
      <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
      <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
      </LayoutView>
    </NotFound>
</Router>

<AntContainer />修改 MainLayout


[*]修改MainLayout.razor。
[*]把MainLayout.razor中默认布局删除
[*]引入AntDesign.ProLayout
[*]设置布局为AntDesign.ProLayout
[*]构造菜单、页脚的链接、版权
[*]wwwroot目录下新建个文件夹images,把提前准备好的logo放进去
完整代码如下:
@using AntDesign.ProLayout
@inherits LayoutComponentBase

<AntDesign.ProLayout.BasicLayout
    Logo="@("images/logo.png")"
    MenuData="MenuData">
    <ChildContent>
      @Body
    </ChildContent>
    <FooterRender>
      <FooterView Copyright="MauiBlazorApp" Links="Links"></FooterView>
    </FooterRender>
</AntDesign.ProLayout.BasicLayout>
<SettingDrawer />

@code
{
    private readonly MenuDataItem[] MenuData =
      {
      new MenuDataItem
      {
            Path = "/",
            Name = "Home",
            Key = "Home",
            Icon = "home"
      },
      new MenuDataItem
      {
            Path = "/Counter",
            Name = "Counter",
            Key = "Counter",
            Icon = "plus"
      },
      new MenuDataItem
      {
            Path = "/FetchData",
            Name = "FetchData",
            Key = "FetchData",
            Icon = "cloud"
      }
    };
    private readonly LinkItem[] Links =
    {
      new LinkItem
      {
            Key = "DotNet宝藏库",
            Title = "基于Ant Design Blazor",
            Href = "https://antblazor.com",
            BlankTarget = true
      }
    };
}这时可以把项目中无用的内容删除掉了,如Shared/NavMenu.razor、wwwroot/css文件。
由于删除掉了css文件夹,页面元素肯定没有样式了。那么就简单的改造下默认的几个页面!
改造默认页面

index.razor

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


替换为Ant Design组件。
@page "/"

<Title Level="1">Hello,DotNet宝藏库</Title>

<br />
<Text Type="success">欢迎关注我的公众号!</Text>Counter.razor

打开 Pages/Counter.razor,将代码改为如下:
@page "/counter"

<Title Level="2">HCounter</Title>

<p role="status">Current count: @currentCount</p>

<Button @onclick="IncrementCount" Type="primary">AntDesign 按钮</Button>
@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
      currentCount++;
    }
}FetchData.razor

打开Pages/FetchData.razor,将数据表格替换为Ant Design,删除页面所有代码,替换为Ant Design的示例!
@page "/fetchdata"
@using System.ComponentModel
@using AntDesign.TableModels
@using System.Text.Json

@using MauiBlazorApp.Data
@inject WeatherForecastService ForecastService

<Table @ref="table"
       TItem="WeatherForecast"
       DataSource="@forecasts"
       Total="_total"
       @bind-PageIndex="_pageIndex"
       @bind-PageSize="_pageSize"
       @bind-SelectedRows="selectedRows"
       OnChange="OnChange">
    <Selection Key="@(context.Id.ToString())" />
    <PropertyColumn Property="c=>c.Id" Sortable />
    <PropertyColumn Property="c=>c.Date" Format="yyyy-MM-dd" Sortable />
    <PropertyColumn Property="c=>c.TemperatureC" Sortable />
    <PropertyColumn Title="Temp. (F)" Property="c=>c.TemperatureF" />
    <PropertyColumn Title="Hot" Property="c=>c.Hot">
      <Switch @bind-Value="@context.Hot"></Switch>
    </PropertyColumn>
    <PropertyColumn Property="c=>c.Summary" Sortable />
    <ActionColumn>
      <Space>
            <SpaceItem><Button Danger OnClick="()=>Delete(context.Id)">Delete</Button></SpaceItem>
      </Space>
    </ActionColumn>
</Table>
<br />
<p>PageIndex: @_pageIndex | PageSize: @_pageSize | Total: @_total</p>

<br />
<h5>selections:</h5>
@if (selectedRows != null && selectedRows.Any())
{
    <Button Danger Size="small" OnClick="@(e => { selectedRows = null; })">Clear</Button>

    @foreach (var selected in selectedRows)
    {
      <Tag @key="selected.Id" Closable OnClose="e=>RemoveSelection(selected.Id)">@selected.Id - @selected.Summary</Tag>
    }
}

<Button Type="@ButtonType.Primary" OnClick="()=> { _pageIndex--; }">Previous page</Button>
<Button Type="@ButtonType.Primary" OnClick="()=> { _pageIndex++; }">Next Page</Button>

@code {
    private WeatherForecast[] forecasts;
    IEnumerable<WeatherForecast> selectedRows;
    ITable table;
    int _pageIndex = 1;
    int _pageSize = 10;
    int _total = 0;

    protected override async Task OnInitializedAsync()
    {
      forecasts = await GetForecastAsync(1, 50);
      _total = 50;
    }
    public class WeatherForecast
    {
      public int Id { get; set; }

      
      public DateTime? Date { get; set; }

      
      public int TemperatureC { get; set; }

      
      public string Summary { get; set; }

      public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

      public bool Hot { get; set; }
    }
    private static readonly string[] Summaries = new[]
    {
      "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };
    public void OnChange(QueryModel<WeatherForecast> queryModel)
    {
      Console.WriteLine(JsonSerializer.Serialize(queryModel));
    }
    public Task<WeatherForecast[]> GetForecastAsync(int pageIndex, int pageSize)
    {
      var rng = new Random();
      return Task.FromResult(Enumerable.Range((pageIndex - 1) * pageSize + 1, pageSize).Select(index =>
      {
            var temperatureC = rng.Next(-20, 55);
            return new WeatherForecast
                {
                  Id = index,
                  Date = DateTime.Now.AddDays(index),
                  TemperatureC = temperatureC,
                  Summary = Summaries,
                  Hot = temperatureC > 30,
                };
      }).ToArray());
    }
    public void RemoveSelection(int id)
    {
      var selected = selectedRows.Where(x => x.Id != id);
      selectedRows = selected;
    }

    private void Delete(int id)
    {
      forecasts = forecasts.Where(x => x.Id != id).ToArray();
      _total = forecasts.Length;
    }
}运行效果:

https://img-blog.csdnimg.cn/12b86d6b1cd54720a8d1a0988a908f7b.png#pic_center
https://img-blog.csdnimg.cn/e57100e3e32f401eb079ebd4e2a0d2a5.png#pic_center
https://img-blog.csdnimg.cn/825e19d950714b938b8441297a7109ea.png#pic_center
https://img-blog.csdnimg.cn/7915c86ddd554ac4b0d894ef0ea013a1.png#pic_center
总结

暂无,下次再会
欢迎大家关注我的微信公众号,一起进步,一起成长https://img2023.cnblogs.com/blog/93324/202212/93324-20221205182127693-712634750.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 学习.NET MAUI Blazor(三)、创建.NET MAUI Blazor应用并使用AntDesignBla