安装和配置 .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 内置控件定义应用范围内的颜色和默认样式。该文件合并两个资源字典:Resources/Colors.xaml和Resources/Styles.xaml。示例代码如下:
<?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。示例代码展示默认模板和事件重写能力:
public partial class App : Application
{
public App()
{
InitializeComponent();
}
protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new AppShell());
}
// 可选的生命周期事件实现
protected override void OnStart()
{
base.OnStart();
}
protected override void OnResume()
{
base.OnResume();
}
protected override void OnSleep()
{
base.OnSleep();
}
}
注意,当应用首次运行时,还可重写特定于平台的生命周期事件,这将在后续说明。
- AppShell.xaml:此文件是 .NET MAUI 应用的主要结构,提供应用样式、基于 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:此文件包含用户界面定义,示例应用包括两个标签、一个按钮和一个图像,使用
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事件处理程序,递增计数器并更新标签文本。使用SemanticScreenReader.Announce方法支持辅助功能,指定屏幕阅读器公布的文本:
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方法。此方法通过应用生成器对象配置应用程序,至少使用UseMauiApp泛型方法指定应用程序类,并提供注册字体、配置服务等方法。示例代码展示字体注册:
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 的特定平台初始化代码文件和资源。初始化后,平台特定代码调用
MauiProgram.CreateMauiApp方法,创建并运行App对象。例如,Android 的 MainApplication.cs、iOS 和 MacCatalyst 的 AppDelegate.cs,以及 Windows 的 App.xaml.cs 都包含重写:
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
.NET MAUI 应用启动时,控制流从本机特定启动开始,到创建 MAUI 应用函数,最后到应用对象构造函数。
项目资源
主项目的项目文件 (.csproj) 包含重要部分。初始 PropertyGroup 指定目标平台框架、应用程序标题、ID、版本、支持的操作系统等属性,可根据需要修改。示例片段:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-android;net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.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>
<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 -->
<MauiAsset Include="Resources\Raw\**"
LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
...
</Project>
在 Visual Studio 的“解决方案资源管理器”中,可展开 Resources 文件夹查看这些项,并可添加其他字体、图像和图形资源。应用运行时,需在 CreateMauiApp 方法中注册添加到 fonts 文件夹的字体,使用 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>
此外,Resources 文件夹用于 Android,而 Platforms 文件夹下的 iOS 文件夹用于 iOS 特定资源,确保跨平台兼容性。