Uno Platform 快速入门
作者:步子哥 (steper@foxmail.com)
1. 什么是 Uno Platform?
1.1 三个比喻看懂 Uno Platform
比喻一:万能翻译官
想象你是一个只会说 C# 的开发者,
你想让你的应用运行在全世界所有设备上:
- Windows 电脑
- Mac 电脑
- iPhone 手机
- Android 手机
- Linux 桌面
- 网页浏览器
每个平台都有自己的"语言":
- Windows 说 WinUI 话
- iOS 说 UIKit 话
- Android 说 Kotlin 话
- 网页说 HTML/CSS 话
传统做法:
你要学会所有语言,然后分别开发 6 个版本的应用。
累不累?当然累!
Uno Platform 的做法:
你只需要用 C# 和 XAML 写一次代码,
Uno 就像一位万能翻译官,
把你的代码"翻译"成每个平台都能理解的原生代码。
用户看到的:
- Windows 用户看到的是地道的 Windows 应用
- Mac 用户看到的是地道的 Mac 应用
- iPhone 用户看到的是地道的 iOS 应用
关键点:
- 一次编写,到处运行
- 每个平台都有原生外观和手感
- 开发者只需要掌握 C# 和 XAML
比喻二:神奇的建筑图纸
Uno Platform 就像一张神奇的建筑图纸:
传统方式:
- 在北京盖房子 → 画北京风格的图纸
- 在上海盖房子 → 画上海风格的图纸
- 在广州盖房子 → 画广州风格的图纸
Uno Platform 方式:
- 画一张通用图纸
- 这张图纸会自动适应当地风格
- 在北京自动变成北京风格
- 在上海自动变成上海风格
- 在广州自动变成广州风格
这就是"Write Once, Run Everywhere"的魔法!
比喻三:跨平台的桥梁
Uno Platform 就像一座连接多个岛屿的桥梁:
┌─────────────┐
│ 你的代码 │
│ (C# + XAML) │
└──────┬──────┘
│
┌──────▼──────┐
│Uno Platform │
│ (桥梁) │
└──────┬──────┘
│
┌──────────┬───────────┼───────────┬──────────┬──────────┐
▼ ▼ ▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│Windows│ │ macOS │ │ Linux │ │ iOS │ │Android│ │ Web │
│ │ │ │ │ │ │ │ │ │ │(Wasm) │
└───────┘ └───────┘ └───────┘ └───────┘ └───────┘ └───────┘
桥梁的作用:
- 你站在中间(写一次代码)
- 桥梁连接到所有岛屿(支持所有平台)
- 每个岛屿的居民都能用自己的方式理解你的代码
1.2 Uno Platform 的前世今生
时间线:
2018年5月:
- nventive 公司发布 Uno Platform
- 基于 UWP(Universal Windows Platform)技术
- 目标:让 Windows 应用运行到所有平台
核心技术栈:
- 编程语言:C# 10+ / XAML
- 运行时:.NET 8.0+
- 架构模式:MVVM(Model-View-ViewModel)
- 许可证:Apache 2.0(完全开源)
为什么叫 "Uno"?
- Uno 在西班牙语和意大利语中意思是"一"
- 寓意:一份代码,一个解决方案
- 强调"单一代码库"的理念
社区生态:
- GitHub 星标:8,000+
- NuGet 下载量:数百万
- 年度会议:UnoConf
- 官方支持:nventive + 社区贡献者
1.3 Uno Platform vs 其他跨平台框架
| 特性 | Uno Platform | .NET MAUI | Flutter | React Native |
|---|---|---|---|---|
| 语言 | C#/XAML | C#/XAML | Dart | JavaScript |
| 渲染方式 | 原生控件 | 原生控件 | 自绘 | 原生控件 |
| Web 支持 | WebAssembly | 无 | 有 | 有 |
| Linux 支持 | 有 | 无 | 有 | 有 |
| Windows API | 完整支持 | 部分支持 | 无 | 无 |
| 学习曲线 | 中等 | 中等 | 中等 | 较低 |
| 原生外观 | 完美 | 好 | 需要定制 | 好 |
| 成熟度 | 成熟 | 新 | 非常成熟 | 非常成熟 |
何时选择 Uno Platform?
选择 Uno 的场景:
- 需要支持 WebAssembly
- 想让桌面应用在浏览器中运行 - 不需要用户安装任何软件 - 一次部署,全球访问
- 需要支持 Linux
- 企业级桌面应用需要 Linux 支持 - MAUI 不支持 Linux
- 有 UWP/WinUI 经验
- 已熟悉 XAML 开发模式 - 想复用现有 Windows 应用代码
- 需要原生外观和手感
- 用户期望应用与系统融合 - 不希望"看起来像跨平台"
2. 环境搭建
2.1 系统要求
| 平台 | 最低要求 | 推荐配置 |
|---|---|---|
| Windows | Windows 10 1809+ | Windows 11 |
| macOS | macOS 10.15+ | macOS 13+ |
| Linux | Ubuntu 18.04+ | Ubuntu 22.04 |
| Visual Studio | 2022 17.8+ | 2022 最新版 |
| .NET SDK | .NET 8.0 | .NET 8.0 最新版 |
2.2 安装 Visual Studio 扩展
方法一:通过 Visual Studio 安装
- 打开 Visual Studio 2022
- 菜单:扩展 → 管理扩展
- 搜索 "Uno Platform"
- 点击"下载",关闭 VS 后自动安装
方法二:通过命令行安装(VS Code 用户)
# 安装 .NET SDK(如果还没有)
winget install Microsoft.DotNet.SDK.8
# 安装 Uno Platform 模板
dotnet new install Uno.Templates
2.3 验证安装
# 查看已安装的模板
dotnet new list uno
# 应该看到类似输出:
# Uno Platform App unoapp [C#] Uno Platform App
# Uno Platform Class Library unolib [C#] Uno Platform Class Library
# Uno Platform Maui Embedding unoapp-maui [C#] Uno Platform Maui Embedding
3. 创建第一个应用
3.1 使用 Visual Studio 创建
步骤 1:创建新项目
- 打开 Visual Studio
- 点击"创建新项目"
- 搜索"Uno"
- 选择"Uno Platform App"
- 点击"下一步"
步骤 2:配置项目
项目名称:HelloUno
位置:选择你的工作目录
框架:.NET 8.0 (长期支持)
步骤 3:选择模板选项
在项目向导中:
| 选项 | 推荐选择 |
|---|---|
| 模板 | Blank(空白模板) |
| 平台 | Windows + WebAssembly + iOS + Android |
| 展示层 | MVVM |
| 导航 | Frame Navigation |
| 日志 | Console |
步骤 4:等待项目创建
首次创建可能需要几分钟,因为要下载 NuGet 包。
3.2 使用命令行创建
# 创建基础项目
dotnet new unoapp -o HelloUno
# 进入项目目录
cd HelloUno
# 查看项目结构
ls
3.3 项目结构解析
HelloUno/
├── HelloUno/ # 共享代码库(核心)
│ ├── App.xaml # 应用程序定义
│ ├── App.xaml.cs # 应用程序逻辑
│ ├── MainPage.xaml # 主页面 UI
│ ├── MainPage.xaml.cs # 主页面逻辑
│ ├── Strings/ # 多语言资源
│ └── Assets/ # 图片、图标等资源
│
├── HelloUno.Windows/ # Windows 平台头项目
├── HelloUno.Wasm/ # WebAssembly 平台头项目
├── HelloUno.Mobile/ # iOS/Android 移动平台
├── HelloUno.Skia.Gtk/ # Linux (GTK) 平台
└── HelloUno.Skia.Wpf/ # WPF 宿主(用于测试)
费曼解释:什么是"头项目"?
头项目就像"翻译器":
HelloUno(共享代码库)
- 包含所有业务逻辑和 UI 代码
- 不关心具体运行在哪个平台
HelloUno.Windows(Windows 头项目)
- 负责把共享代码"翻译"成 Windows 应用
- 包含 Windows 特定的配置
HelloUno.Wasm(WebAssembly 头项目)
- 负责把共享代码"翻译"成网页应用
- 包含 WebAssembly 特定的配置
类比:
- 共享代码 = 你的演讲稿
- 头项目 = 翻译员
- 在中国用中文翻译员
- 在美国用英文翻译员
- 演讲稿只需要写一份!
4. 编写第一个界面
4.1 打开主页面
在 HelloUno 共享项目中,打开 MainPage.xaml。
4.2 修改 XAML 代码
将默认内容替换为:
<Page x:Class="HelloUno.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HelloUno"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundBrush}">
<Grid>
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="20">
<TextBlock Text="Hello Uno Platform!"
FontSize="36"
FontWeight="Bold"
HorizontalAlignment="Center"/>
<TextBlock Text="跨平台开发从未如此简单"
FontSize="18"
Foreground="Gray"
HorizontalAlignment="Center"/>
<Slider x:Name="FontSizeSlider"
Minimum="12"
Maximum="72"
Value="36"
Width="300"/>
<TextBlock Text="{Binding Value, ElementName=FontSizeSlider, Mode=OneWay}"
FontSize="{Binding Value, ElementName=FontSizeSlider, Mode=OneWay}"
HorizontalAlignment="Center"/>
<Button Content="点击我"
HorizontalAlignment="Center"
Click="OnButtonClick"/>
</StackPanel>
</Grid>
</Page>
4.3 添加后端代码
打开 MainPage.xaml.cs,添加按钮点击事件:
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace HelloUno;
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void OnButtonClick(object sender, RoutedEventArgs e)
{
// 显示一个简单的对话框
var dialog = new ContentDialog
{
Title = "你好!",
Content = "欢迎来到 Uno Platform 的世界!",
CloseButtonText = "确定",
XamlRoot = this.XamlRoot
};
_ = dialog.ShowAsync();
}
}
4.4 代码详解
Grid 和 StackPanel
Grid(网格):
- 最常用的布局容器
- 可以容纳多个子元素
- 子元素默认重叠(可以通过行列控制)
StackPanel(堆栈面板):
- 水平或垂直排列子元素
- Spacing="20" 表示子元素之间间距 20 像素
- HorizontalAlignment="Center" 水平居中
- VerticalAlignment="Center" 垂直居中
数据绑定
Text="{Binding Value, ElementName=FontSizeSlider}"
这是一个数据绑定表达式:
- Binding:绑定命令
- Value:绑定的属性(Slider 的当前值)
- ElementName:绑定的源元素名称
- Mode=OneWay:单向绑定(Slider → TextBlock)
效果:
当滑块移动时,TextBlock 的文字大小自动变化!
5. 运行应用
5.1 在 Windows 上运行
# 在 Visual Studio 中
1. 选择 HelloUno.Windows 作为启动项目
2. 选择 x64 或 x86 平台
3. 按 F5 或点击"运行"按钮
# 命令行方式
cd HelloUno.Windows
dotnet run
5.2 在 WebAssembly 上运行
# 在 Visual Studio 中
1. 选择 HelloUno.Wasm 作为启动项目
2. 按 F5 运行
3. 浏览器会自动打开应用
# 命令行方式
cd HelloUno.Wasm
dotnet run
浏览器访问 http://localhost:5000 即可看到应用。
5.3 在移动设备上运行
iOS:
# 需要 Mac 电脑 + Xcode
cd HelloUno.Mobile
dotnet build -f net8.0-ios
Android:
# 需要安装 Android SDK
cd HelloUno.Mobile
dotnet build -f net8.0-android
6. 核心 UI 控件
6.1 常用控件一览
| 控件 | 用途 | 示例 |
|---|---|---|
| TextBlock | 显示文本 | <TextBlock Text="Hello"/> |
| TextBox | 输入文本 | <TextBox PlaceholderText="输入..."/> |
| Button | 按钮 | <Button Content="点击"/> |
| CheckBox | 复选框 | <CheckBox Content="同意"/> |
| RadioButton | 单选按钮 | <RadioButton Content="选项A"/> |
| ComboBox | 下拉框 | <ComboBox>...</ComboBox> |
| ListBox | 列表框 | <ListBox>...</ListBox> |
| Image | 图片 | <Image Source="Assets/logo.png"/> |
| Slider | 滑块 | <Slider Minimum="0" Maximum="100"/> |
| ProgressBar | 进度条 | <ProgressBar Value="50"/> |
6.2 布局容器
五大布局容器:
1. Grid(网格)
- 使用行和列定义布局
- 最灵活,最常用
2. StackPanel(堆栈)
- 水平或垂直排列
- 简单易用
3. WrapGrid(换行网格)
- 自动换行排列
- 适合不确定数量的元素
4. Canvas(画布)
- 绝对定位
- 适合游戏或自定义绑定
5. RelativePanel(相对面板)
- 相对定位
- 元素之间可以相互绑定位置
6.3 Grid 布局示例
<Grid>
<!-- 定义 2 行 2 列 -->
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <!-- 自动高度 -->
<RowDefinition Height="*"/> <!-- 占满剩余空间 -->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/> <!-- 固定宽度 -->
<ColumnDefinition Width="*"/> <!-- 占满剩余空间 -->
</Grid.ColumnDefinitions>
<!-- 放置控件 -->
<TextBlock Grid.Row="0" Grid.Column="0" Text="姓名:"/>
<TextBox Grid.Row="0" Grid.Column="1" PlaceholderText="请输入姓名"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="简介:"/>
<TextBox Grid.Row="1" Grid.Column="1" AcceptsReturn="True"/>
</Grid>
7. MVVM 架构入门
7.1 什么是 MVVM?
MVVM = Model-View-ViewModel
┌─────────────────────────────────────────────┐
│ View │
│ (XAML 界面) │
│ │
│ - 显示数据 │
│ - 接收用户操作 │
│ - 绑定到 ViewModel │
└─────────────────┬───────────────────────────┘
│ 数据绑定
┌─────────────────▼───────────────────────────┐
│ ViewModel │
│ (C# 业务逻辑) │
│ │
│ - 暴露属性供 View 绑定 │
│ - 处理用户操作 │
│ - 调用 Model 获取数据 │
└─────────────────┬───────────────────────────┘
│ 调用
┌─────────────────▼───────────────────────────┐
│ Model │
│ (数据和服务) │
│ │
│ - 数据模型 │
│ - 数据库访问 │
│ - API 调用 │
└─────────────────────────────────────────────┘
7.2 创建 ViewModel
// ViewModels/MainViewModel.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace HelloUno.ViewModels;
public class MainViewModel : INotifyPropertyChanged
{
private string _message = "Hello Uno!";
public string Message
{
get => _message;
set
{
if (_message != value)
{
_message = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
7.3 在 View 中绑定
<Page ...
xmlns:vm="using:HelloUno.ViewModels">
<Page.DataContext>
<vm:MainViewModel/>
</Page.DataContext>
<Grid>
<TextBlock Text="{Binding Message}"
FontSize="24"/>
</Grid>
</Page>
8. 热重载(Hot Reload)
8.1 什么是热重载?
热重载让你在应用运行时修改代码,
无需重启应用,修改立即生效!
传统开发流程:
修改代码 → 停止应用 → 重新编译 → 重新启动 → 查看效果
(耗时 30 秒到几分钟)
热重载流程:
修改代码 → 保存 → 立即看到效果
(耗时 1 秒!)
8.2 启用热重载
Visual Studio:
- 工具 → 选项 → 调试 → 热重载
- 勾选"在调试时启用热重载"
- 勾选"在保存时应用热重载"
VS Code:
# 安装 C# Hot Reload 扩展
# 运行时添加 --no-build 标志
dotnet watch run
8.3 使用热重载
1. 按 F5 启动应用
2. 保持应用运行
3. 修改 XAML 文件
4. 按 Ctrl+S 保存
5. 应用立即更新!
9. Uno Toolkit 快速上手
9.1 安装 Uno.Toolkit
# 在项目中添加 NuGet 包
dotnet add package Uno.Toolkit.UI
dotnet add package Uno.Toolkit.WinUI
9.2 常用控件
TabBar(标签栏)
<Page ...
xmlns:utu="using:Uno.Toolkit.UI">
<Grid>
<utu:TabBar>
<utu:TabBarItem Content="首页">
<utu:TabBarItem.Icon>
<SymbolIcon Symbol="Home"/>
</utu:TabBarItem.Icon>
</utu:TabBarItem>
<utu:TabBarItem Content="搜索">
<utu:TabBarItem.Icon>
<SymbolIcon Symbol="Find"/>
</utu:TabBarItem.Icon>
</utu:TabBarItem>
<utu:TabBarItem Content="设置">
<utu:TabBarItem.Icon>
<SymbolIcon Symbol="Setting"/>
</utu:TabBarItem.Icon>
</utu:TabBarItem>
</utu:TabBar>
</Grid>
</Page>
NavBar(导航栏)
<utu:NavBar Content="我的应用"
MainCommandMode="Back">
<utu:NavBar.PrimaryCommands>
<AppBarButton Icon="Add" Label="添加"/>
<AppBarButton Icon="Edit" Label="编辑"/>
</utu:NavBar.PrimaryCommands>
</utu:NavBar>
10. 主题与样式
10.1 安装主题包
# Material Design 主题
dotnet add package Uno.Material
# Fluent Design 主题
dotnet add package Uno.Fluent
# Cupertino (iOS 风格) 主题
dotnet add package Uno.Cupertino
10.2 应用主题
在 App.xaml 中:
<Application ...
xmlns:material="using:Uno.Material">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Material 主题 -->
<material:XamlControlsResources/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
10.3 使用主题颜色
<Button Content="主要按钮"
Style="{StaticResource FilledButtonStyle}"/>
<Button Content="次要按钮"
Style="{StaticResource OutlinedButtonStyle}"/>
<Button Content="文字按钮"
Style="{StaticResource TextButtonStyle}"/>
11. 从 Figma 设计到代码
11.1 安装 Figma 插件
- 打开 Figma
- 进入 Figma 社区
- 搜索 "Uno Platform"
- 安装 "Uno Platform (Figma to C# or XAML)" 插件
11.2 设计工作流
1. 在 Figma 中使用 Uno Material Toolkit 组件设计界面
2. 选择要导出的设计
3. 右键 → Plugins → Uno Platform
4. 选择 Preview 预览效果
5. 选择 Export 导出代码
6. 选择 XAML 或 C# Markup
7. 复制代码到 Visual Studio
11.3 导出选项
| 选项 | 说明 |
|---|---|
| XAML | 传统的 XAML 标记语言 |
| C# Markup | 使用 C# 代码构建 UI |
| Color Override | 颜色主题文件 |
| Fonts Override | 字体配置文件 |
12. 调试与部署
12.1 调试技巧
断点调试:
// 在任意代码行设置断点
// 按 F5 启动调试
// 程序会在断点处暂停
输出窗口:
using System.Diagnostics;
Debug.WriteLine("调试信息");
Debug.WriteLine($"当前值: {value}");
日志记录:
using Microsoft.Extensions.Logging;
// 在构造函数中注入 ILogger
public MainPage(ILogger<MainPage> logger)
{
_logger = logger;
_logger.LogInformation("页面已加载");
}
12.2 部署到 Windows Store
# 1. 创建发布版本
dotnet publish -c Release -f net8.0-windows10.0.19041.0
# 2. 使用 Windows App SDK 打包
# 参考:https://learn.microsoft.com/windows/apps/package/
12.3 部署到 WebAssembly
# 1. 创建发布版本
dotnet publish -c Release
# 2. 输出在 bin/Release/net8.0/publish/wwwroot
# 3. 将 wwwroot 目录上传到任何静态网站托管服务
# - Azure Static Web Apps
# - GitHub Pages
# - Netlify
# - Vercel
13. 常见问题解决
13.1 NuGet 包恢复失败
# 清除 NuGet 缓存
dotnet nuget locals all --clear
# 重新恢复包
dotnet restore
13.2 WebAssembly 调试
# 启用 WebAssembly 调试
# 在 launchSettings.json 中添加:
{
"profiles": {
"HelloUno.Wasm": {
"commandName": "Project",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
}
}
}
13.3 平台特定代码
// 使用条件编译
#if WINDOWS
// Windows 特定代码
#elif __WASM__
// WebAssembly 特定代码
#elif __ANDROID__
// Android 特定代码
#elif __IOS__
// iOS 特定代码
#endif
14. 学习资源
14.1 官方资源
| 资源 | 链接 |
|---|---|
| 官方文档 | https://platform.uno/docs/ |
| 入门教程 | https://platform.uno/docs/articles/getting-started-tutorial-1.html |
| GitHub 仓库 | https://github.com/unoplatform/uno |
| YouTube 频道 | https://www.youtube.com/@UnoPlatform |
| Discord 社区 | https://discord.gg/uno-platform |
14.2 示例项目
| 项目 | 说明 |
|---|---|
| Uno Chat | 完整的聊天应用示例 |
| Uno Todo | 任务管理应用 |
| Uno Commerce | 电商应用模板 |
| Uno GitHub | GitHub 客户端示例 |
14.3 推荐学习路径
第 1 周:基础入门
├── 环境搭建
├── 创建第一个应用
├── 学习 XAML 基础
└── 理解 MVVM 架构
第 2 周:进阶开发
├── 掌握布局系统
├── 学习数据绑定
├── 使用主题和样式
└── 探索 Uno Toolkit
第 3 周:项目实战
├── 从 Figma 设计开始
├── 实现完整功能
├── 添加平台特定代码
└── 部署到多个平台
第 4 周:深入优化
├── 性能优化
├── 单元测试
├── CI/CD 集成
└── 发布应用
15. 本章小结
关键要点回顾
- Uno Platform 是什么?
- 开源跨平台 UI 框架 - 基于 WinUI/UWP 技术 - 一次编写,运行在 6+ 平台
- 为什么选择 Uno?
- WebAssembly 支持 - Linux 支持 - 原生外观和手感 - 与 Windows 生态深度融合
- 核心概念
- XAML:声明式 UI 标记语言 - MVVM:架构模式 - 数据绑定:View 和 ViewModel 的桥梁 - 头项目:平台特定的引导项目
- 开发流程
- 安装 Visual Studio 扩展 - 创建项目(选择目标平台) - 编写共享代码 - 运行和调试 - 部署到目标平台
下一步学习
现在你已经掌握了 Uno Platform 的基础知识,
建议继续学习:
1. 深入 MVVM 架构
- CommunityToolkit.Mvvm
- 依赖注入
- 消息中心
2. 高级主题
- 自定义控件
- 动画系统
- 平台互操作
3. 实战项目
- 完整的应用开发
- 团队协作
- 持续集成
练习题:
- 创建一个简单的计数器应用,包含一个显示数字的 TextBlock 和两个 Button(加/减)。
- 使用 MVVM 模式重构上述应用,将业务逻辑移到 ViewModel 中。
- 在 WebAssembly 平台运行你的应用,并尝试热重载功能。
(提示:Button 的 Command 属性可以绑定到 ViewModel 中的 ICommand)