在 Visual Studio 中创建 .NET MAUI 项目
安装并配置 .NET MAUI 工具后,可以使用 Visual Studio 生成 .NET MAUI 应用。
在本单元中,你将了解 Visual Studio 中 .NET MAUI 模板的结构。 你将使用此模板创建跨平台移动和桌面应用。
如何入门
若要使用 Visual Studio 创建新的 .NET MAUI 项目,请在“创建新项目”对话框中选择 .NET MAUI 项目类型,然后选择 .NET MAUI 应用模板:
按照向导中的步骤命名项目并指定位置。
新创建的 .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
属性;此属性确定应用程序开始运行时显示哪个页面。 此外,此类使你能够替代常见的平台中性应用程序生命周期事件处理程序。 事件包括OnStart
、OnResume
和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 应用启动时的控制流:
项目资源
主项目的 .csproj 文件包含几个值得注意的部分。 初始 PropertyGroup
指定项目面向的平台框架,以及应用程序标题、ID、版本、显示版本和支持的操作系统等项。 可以根据需要修改这些属性。
<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
部分,可在第一个窗口出现之前,为应用加载时出现的初始屏幕指定图像和颜色。 还可以为应用使用的字体、图像和资产设置默认位置。
<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 文件夹来查看这些项。 可以将应用程序所需的任何其他字体、图像和其他图形资源添加到此文件夹和子文件夹。
应用开始运行时,应向应用生成器对象注册添加到 fonts 文件夹中的任何字体。 回想一下,MauiProgram 类中的 CreateMauiApp 方法使用 ConfigureFonts
方法执行此操作:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
...
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
...
}
}
在此示例中,AddFont
方法将字体与名称 OpenSansRegular
关联。 在页面的 XAML 说明或应用程序资源字典中设置项格式时,可以指定此字体:
<Application ...">
<Application.Resources>
<ResourceDictionary>
...
<Style TargetType="Button">
...
<Setter Property="FontFamily" Value="OpenSansRegular" />
...
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
在 Android 中使用 Resources 文件夹,并为 Android 和 iOS 特定于平台的资源使用 Platforms 文件夹下的 iOS 文件夹。