在 Visual Studio 中创建 .NET MAUI 项目

发布时间 2023-09-25 10:08:00作者: 韩梦芫

安装并配置 .NET MAUI 工具后,可以使用 Visual Studio 生成 .NET MAUI 应用。

在本单元中,你将了解 Visual Studio 中 .NET MAUI 模板的结构。 你将使用此模板创建跨平台移动和桌面应用。

如何入门

若要使用 Visual Studio 创建新的 .NET MAUI 项目,请在“创建新项目”对话框中选择 .NET MAUI 项目类型,然后选择 .NET MAUI 应用模板:

Visual Studio 中“创建新项目”对话框的屏幕截图。用户已选择 .NET MAUI 应用模板。

按照向导中的步骤命名项目并指定位置。

新创建的 .NET MAUI 项目包含如下所示的项:

屏幕截图显示 Visual Studio 中新 .NET MAUI 解决方案的默认结构的解决方案资源管理器。

.NET MAUI 项目结构和应用程序启动

项目内容包括以下项:

  • App.xaml。 此文件定义应用将在 XAML 布局中使用的应用程序资源。 默认资源位于 Resources 文件夹中,并为每个 .NET MAUI 内置控件定义应用范围内的颜色和默认样式。 在此处,你会看到将合并在一起的两个资源字典:

    XML
    <?xml version = "1.0" encoding = "UTF-8" ?>
    <Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:MyMauiApp"
                 x:Class="MyMauiApp.App">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Resources/Colors.xaml" />
                    <ResourceDictionary Source="Resources/Styles.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    
  • App.xaml.cs。 这是 App.xaml 文件的代码隐藏文件。 此文件定义 App 类。 此类表示运行时的应用程序。 此类中的构造函数创建一个初始窗口并将其分配给 MainPage 属性;此属性确定应用程序开始运行时显示哪个页面。 此外,此类使你能够替代常见的平台中性应用程序生命周期事件处理程序。 事件包括 OnStartOnResume 和 OnSleep。 这些处理程序定义为 Application 基类的成员。 下面的代码演示了示例:

     备注

    当应用首次开始运行时,还可以替代特定于平台的生命周期事件。 稍后将对此进行说明。

    C#
    namespace MyMauiApp;
    
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
    
            MainPage = new AppShell();
        }
    
        protected override void OnStart()
        {
            base.OnStart();
        }
    
        protected override void OnResume()
        {
            base.OnResume();
        }
    
        protected override void OnSleep()
        {
            base.OnSleep();
        }
    }
    
  • AppShell.xaml。 此文件是 .NET MAUI 应用程序的主要结构。 .NET MAUI Shell 提供了许多对多平台应用有益的功能,包括应用样式、基于 URI 的导航、布局选项(例如浮出控件导航、应用程序根文件的选项卡)。 默认模板提供在应用启动时扩充的单个页面(或 ShellContent)。

    XML
      <?xml version="1.0" encoding="UTF-8" ?>
      <Shell
          x:Class="MyMauiApp.AppShell"
          xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          xmlns:local="clr-namespace:MyMauiApp"
          Shell.FlyoutBehavior="Disabled">
    
          <ShellContent
              Title="Home"
              ContentTemplate="{DataTemplate local:MainPage}"
              Route="MainPage" />
    
      </Shell>
    
  • MainPage.xaml。 此文件包含用户界面定义。 MAUI 应用模板生成的示例应用包括两个标签、一个按钮和一个图像。 这些控件是使用包含在 ScrollView 中的 VerticalStackLayout 排列的。 VerticalStackLayout 控件可垂直排列控件(堆叠显示),而 ScrollView 提供滚动条,当视图太大而无法在设备上显示时可使用该滚动条。 你打算将此文件的内容替换为自己的 UI 布局。 如果有多页应用,还可以定义更多 XAML 页面。

    XML
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="MyMauiApp.MainPage">
    
        <ScrollView>
            <VerticalStackLayout 
                Spacing="25" 
                Padding="30,0" 
                VerticalOptions="Center">
    
                <Image
                    Source="dotnet_bot.png"
                    SemanticProperties.Description="Cute dot net bot waving hi to you!"
                    HeightRequest="200"
                    HorizontalOptions="Center" />
    
                <Label 
                    Text="Hello, World!"
                    SemanticProperties.HeadingLevel="Level1"
                    FontSize="32"
                    HorizontalOptions="Center" />
    
                <Label 
                    Text="Welcome to .NET Multi-platform App UI"
                    SemanticProperties.HeadingLevel="Level2"
                    SemanticProperties.Description="Welcome to dot net Multi platform App U I"
                    FontSize="18"
                    HorizontalOptions="Center" />
    
                <Button 
                    x:Name="CounterBtn"
                    Text="Click me"
                    SemanticProperties.Hint="Counts the number of times you click"
                    Clicked="OnCounterClicked"
                    HorizontalOptions="Center" />
    
            </VerticalStackLayout>
        </ScrollView>
    
    </ContentPage>
    
  • MainPage.xaml.cs。 这是页面的代码隐藏文件。 在此文件中,为页面上的控件触发的各种事件处理程序和其他操作定义逻辑。 示例代码实现页面上的按钮的 Clicked 事件处理程序。 代码只是递增计数器变量,并在页面上的标签中显示结果。 作为 MAUI Essentials 库的一部分提供的语义服务支持辅助功能。 SemanticScreenReader 类的静态 Announce 方法指定用户选择按钮时屏幕阅读器公布的文本:

    C#
    namespace MyMauiApp;
    
    public partial class MainPage : ContentPage
    {
        int count = 0;
    
        public MainPage()
        {
            InitializeComponent();
        }
    
        private void OnCounterClicked(object sender, EventArgs e)
        {
            count++;
    
            if (count == 1)
                CounterBtn.Text = $"Clicked {count} time";
            else
                CounterBtn.Text = $"Clicked {count} times";
    
            SemanticScreenReader.Announce(CounterBtn.Text);
        }
    }
    
  • MauiProgram.cs。 每个本机平台都有一个不同的起点,用于创建和初始化应用程序。 可以在项目中的 Platforms 文件夹中找到此代码。 此代码特定于平台,但最后调用静态 MauiProgram 类的 CreateMauiApp 方法。 使用 CreateMauiApp 方法通过创建应用生成器对象来配置应用程序。 至少需要指定描述应用程序的类。 使用应用生成器对象的 UseMauiApp 泛型方法执行此操作;类型参数指定应用程序类。 应用生成器还提供用于注册字体、为依赖项注入配置服务、为控件注册自定义处理程序等任务的方法。 以下代码展示了使用应用生成器注册字体的示例:

    C#
    namespace MyMauiApp;
    
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });
    
            return builder.Build();
        }
    }
    
  • Platforms。 此文件夹包含特定于平台的初始化代码文件和资源。 有适用于 Android、iOS、MacCatalyst、Tizen 和 Windows 的文件夹。 在运行时,应用以特定于平台的方式启动。 大部分启动过程从 MAUI 库的内部抽离出来,但这些文件夹中的代码文件提供了挂钩自己的自定义初始化的机制。 重要的是,初始化完成后,特定于平台的代码将调用 MauiProgram.CreateMauiApp 方法,然后按照前面所述创建和运行 App 对象。 例如,Android 文件夹中的 MainApplication.cs 文件、iOS 和 MacCatalyst 文件夹中的 AppDelegate.cs 文件,以及 Windows 文件夹中的 App.xaml.cs 文件都包含替代:

    C#
    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
    

下图演示了 .NET MAUI 应用启动时的控制流:

关系图显示 .NET MAUI 应用启动时的控制流。此流从本机特定的启动到创建 MAUI 应用函数,最后到应用对象构造函数。

项目资源

主项目的 .csproj 文件包含几个值得注意的部分。 初始 PropertyGroup 指定项目面向的平台框架,以及应用程序标题、ID、版本、显示版本和支持的操作系统等项。 可以根据需要修改这些属性。

XML
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
        <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
        <!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
        <!-- <TargetFrameworks>$(TargetFrameworks);net6.0-tizen</TargetFrameworks> -->
        <OutputType>Exe</OutputType>
        <RootNamespace>MyMauiApp</RootNamespace>
        <UseMaui>true</UseMaui>
        <SingleProject>true</SingleProject>
        <ImplicitUsings>enable</ImplicitUsings>

        <!-- Display name -->
        <ApplicationTitle>MyMauiApp</ApplicationTitle>

        <!-- App Identifier -->
        <ApplicationId>com.companyname.mymauiapp</ApplicationId>
        <ApplicationIdGuid>272B9ECE-E038-4E53-8553-E3C9EA05A5B2</ApplicationIdGuid>

        <!-- Versions -->
        <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
        <ApplicationVersion>1</ApplicationVersion>

        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
        <TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
    </PropertyGroup>
    ...

</Project>

通过初始属性组下的 ItemGroup 部分,可在第一个窗口出现之前,为应用加载时出现的初始屏幕指定图像和颜色。 还可以为应用使用的字体、图像和资产设置默认位置。

XML
<Project Sdk="Microsoft.NET.Sdk">

    ...

   <ItemGroup>
        <!-- App Icon -->
        <MauiIcon Include="Resources\appicon.svg" 
                  ForegroundFile="Resources\appiconfg.svg" 
                  Color="#512BD4" />

        <!-- Splash Screen -->
        <MauiSplashScreen Include="Resources\appiconfg.svg" 
                          Color="#512BD4" 
                          BaseSize="128,128" />

        <!-- Images -->
        <MauiImage Include="Resources\Images\*" />
        <MauiImage Update="Resources\Images\dotnet_bot.svg" 
                   BaseSize="168,208" />

        <!-- Custom Fonts -->
        <MauiFont Include="Resources\Fonts\*" />

        <!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
        <MauiAsset Include="Resources\Raw\**" 
                   LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
    </ItemGroup>

    ...

</Project>

在 Visual Studio 的“解决方案资源管理器”窗口中,可以展开 Resources 文件夹来查看这些项。 可以将应用程序所需的任何其他字体、图像和其他图形资源添加到此文件夹和子文件夹。

屏幕截图显示 Visual Studio 解决方案资源管理器的主项目中的资源文件夹,它包围在一个矩形内。文件夹内是字体和图像文件。

应用开始运行时,应向应用生成器对象注册添加到 fonts 文件夹中的任何字体。 回想一下,MauiProgram 类中的 CreateMauiApp 方法使用 ConfigureFonts 方法执行此操作:

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

        ...
    }
}

在此示例中,AddFont 方法将字体与名称 OpenSansRegular 关联。 在页面的 XAML 说明或应用程序资源字典中设置项格式时,可以指定此字体:

XML
<Application ...">
    <Application.Resources>
        <ResourceDictionary>
            ...
            <Style TargetType="Button">
                ...
                <Setter Property="FontFamily" Value="OpenSansRegular" />
                ...
            </Style>

        </ResourceDictionary>
    </Application.Resources>
</Application>

在 Android 中使用 Resources 文件夹,并为 Android 和 iOS 特定于平台的资源使用 Platforms 文件夹下的 iOS 文件夹。