在 Visual Studio 中创建 .NET MAUI 项目
- 5 分钟
安装和配置 .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 (Extensible Application Markup Language) 布局中使用的应用程序资源。 默认资源位于
Resources文件夹中,并为每个 .NET MAUI 内置控件定义应用范围内的颜色和默认样式。 在此处,你会看到将合并在一起的两个资源字典:<?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基类的成员。 以下代码显示了默认模板的示例,以及替代这些事件的能力:注意
当应用首次开始运行时,还可以替代特定于平台的生命周期事件。 稍后将对此进行说明。
public partial class App : Application { public App() { InitializeComponent(); } protected override Window CreateWindow(IActivationState? activationState) { return new Window(new AppShell()); } // Optional events to implement for the application lifecycle. The Window created // above also has lifecycle events that can be used to track the Window lifecycle. 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 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="Flyout" Title="MyMauiApp"> <ShellContent Title="Home" ContentTemplate="{DataTemplate local:MainPage}" Route="MainPage" /> </Shell>MainPage.xaml。 此文件包含用户界面定义。 MAUI 应用模板生成的示例应用包括两个标签、一个按钮和一个图像。 这些控件是使用包含在
VerticalStackLayout中的ScrollView排列的。VerticalStackLayout元素可垂直排列控件(堆叠显示),而ScrollView提供滚动条,当视图太大而无法在设备上显示时可使用该滚动条。 你打算将此文件的内容替换为自己的 UI 布局。 如果有多页应用,还可以定义更多 XAML 页面。<?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 Padding="30,0" Spacing="25"> <Image Source="dotnet_bot.png" HeightRequest="185" Aspect="AspectFit" SemanticProperties.Description="dot net bot in a hovercraft number nine" /> <Label Text="Hello, World!" Style="{StaticResource Headline}" SemanticProperties.HeadingLevel="Level1" /> <Label Text="Welcome to .NET Multi-platform App UI" Style="{StaticResource SubHeadline}" SemanticProperties.HeadingLevel="Level2" SemanticProperties.Description="Welcome to dot net Multi platform App U I" /> <Button x:Name="CounterBtn" Text="Click me" SemanticProperties.Hint="Counts the number of times you click" Clicked="OnCounterClicked" HorizontalOptions="Fill" /> </VerticalStackLayout> </ScrollView> </ContentPage>MainPage.xaml.cs。 此文件包含页面的隐藏代码。 在此文件中,你将为页面上的控件触发的各种事件处理程序和其他操作定义逻辑。 示例代码实现页面上的按钮的
Clicked事件处理程序。 代码只是递增计数器变量,并在页面上的标签中显示结果。 作为 MAUI Essentials 库的一部分提供的语义服务支持辅助功能。Announce类的静态SemanticScreenReader方法指定用户选择按钮时屏幕阅读器公布的文本: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 文件夹中找到此代码。 此代码特定于平台,但最后调用静态
CreateMauiApp类的MauiProgram方法。 使用CreateMauiApp方法通过创建应用生成器对象来配置应用程序。 至少,需要使用应用生成器对象的UseMauiApp泛型方法指定描述应用程序的类;类型参数 (<App>) 指定应用程序类。 应用生成器还提供用于注册字体、为依赖项注入配置服务、为控件注册自定义处理程序等任务的方法。 以下代码展示了使用应用生成器注册字体的示例:using Microsoft.Extensions.Logging; 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"); }); #if DEBUG builder.Logging.AddDebug(); #endif return builder.Build(); } }Platforms。 此文件夹包含特定于平台的初始化代码文件和资源。 有适用于 Android、iOS、MacCatalyst、Tizen 和 Windows 的文件夹。 在运行时,应用以特定于平台的方式启动。 MAUI 库提取了大部分的启动过程,但这些文件夹中的代码文件提供了一种与自己的自定义初始化挂钩的机制。 重要的是,初始化完成后,特定于平台的代码将调用
MauiProgram.CreateMauiApp方法,然后按照前面所述创建和运行App对象。 例如,Android 文件夹中的 MainApplication.cs 文件、iOS 和 MacCatalyst 文件夹中的 AppDelegate.cs 文件,以及 Windows 文件夹中的 App.xaml.cs 文件都包含替代:protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
下图演示了 .NET MAUI 应用启动时的控制流:
项目资源
主项目的项目文件 (.csproj) 包含几个值得注意的部分。 初始 PropertyGroup 指定项目面向的平台框架,以及应用程序标题、ID、版本、显示版本和支持的操作系统等项。 可以根据需要修改这些属性。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>MyMauiApp</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Display name -->
<ApplicationTitle>MyMauiApp</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.companyname.mymauiapp</ApplicationId>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
<WindowsPackageType>None</WindowsPackageType>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.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\appicon.svg"
ForegroundFile="Resources\AppIcon\appiconfg.svg"
Color="#512BD4" />
<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg"
Color="#512BD4"
BaseSize="128,128" />
<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.png"
Resize="True" BaseSize="300,185" />
<!-- 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 说明、应用程序或在共享资源字典中设置项格式时,可以指定此字体:
<ResourceDictionary ..>
...
<Style TargetType="Button">
...
<Setter Property="FontFamily" Value="OpenSansRegular" />
...
</Style>
</ResourceDictionary>
在 Android 中使用 Resources 文件夹,并为 Android 和 iOS 特定于平台的资源使用 Platforms 文件夹下的 iOS 文件夹。