Uno Platform 快速入门

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 MAUIFlutterReact Native
语言C#/XAMLC#/XAMLDartJavaScript
渲染方式原生控件原生控件自绘原生控件
Web 支持WebAssembly
Linux 支持
Windows API完整支持部分支持
学习曲线中等中等中等较低
原生外观完美需要定制
成熟度成熟非常成熟非常成熟

何时选择 Uno Platform?

选择 Uno 的场景:

  1. 需要支持 WebAssembly

- 想让桌面应用在浏览器中运行 - 不需要用户安装任何软件 - 一次部署,全球访问

  1. 需要支持 Linux

- 企业级桌面应用需要 Linux 支持 - MAUI 不支持 Linux

  1. 有 UWP/WinUI 经验

- 已熟悉 XAML 开发模式 - 想复用现有 Windows 应用代码

  1. 需要原生外观和手感

- 用户期望应用与系统融合 - 不希望"看起来像跨平台"


2. 环境搭建

2.1 系统要求

平台最低要求推荐配置
WindowsWindows 10 1809+Windows 11
macOSmacOS 10.15+macOS 13+
LinuxUbuntu 18.04+Ubuntu 22.04
Visual Studio2022 17.8+2022 最新版
.NET SDK.NET 8.0.NET 8.0 最新版

2.2 安装 Visual Studio 扩展

方法一:通过 Visual Studio 安装

  1. 打开 Visual Studio 2022
  2. 菜单:扩展 → 管理扩展
  3. 搜索 "Uno Platform"
  4. 点击"下载",关闭 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:创建新项目

  1. 打开 Visual Studio
  2. 点击"创建新项目"
  3. 搜索"Uno"
  4. 选择"Uno Platform App"
  5. 点击"下一步"

步骤 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:

  1. 工具 → 选项 → 调试 → 热重载
  2. 勾选"在调试时启用热重载"
  3. 勾选"在保存时应用热重载"

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>
<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 插件

  1. 打开 Figma
  2. 进入 Figma 社区
  3. 搜索 "Uno Platform"
  4. 安装 "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 GitHubGitHub 客户端示例

14.3 推荐学习路径

第 1 周:基础入门
├── 环境搭建
├── 创建第一个应用
├── 学习 XAML 基础
└── 理解 MVVM 架构

第 2 周:进阶开发
├── 掌握布局系统
├── 学习数据绑定
├── 使用主题和样式
└── 探索 Uno Toolkit

第 3 周:项目实战
├── 从 Figma 设计开始
├── 实现完整功能
├── 添加平台特定代码
└── 部署到多个平台

第 4 周:深入优化
├── 性能优化
├── 单元测试
├── CI/CD 集成
└── 发布应用

15. 本章小结

关键要点回顾

  1. Uno Platform 是什么?

- 开源跨平台 UI 框架 - 基于 WinUI/UWP 技术 - 一次编写,运行在 6+ 平台

  1. 为什么选择 Uno?

- WebAssembly 支持 - Linux 支持 - 原生外观和手感 - 与 Windows 生态深度融合

  1. 核心概念

- XAML:声明式 UI 标记语言 - MVVM:架构模式 - 数据绑定:View 和 ViewModel 的桥梁 - 头项目:平台特定的引导项目

  1. 开发流程

- 安装 Visual Studio 扩展 - 创建项目(选择目标平台) - 编写共享代码 - 运行和调试 - 部署到目标平台

下一步学习

现在你已经掌握了 Uno Platform 的基础知识,
建议继续学习:

1. 深入 MVVM 架构
   - CommunityToolkit.Mvvm
   - 依赖注入
   - 消息中心

2. 高级主题
   - 自定义控件
   - 动画系统
   - 平台互操作

3. 实战项目
   - 完整的应用开发
   - 团队协作
   - 持续集成

练习题:

  1. 创建一个简单的计数器应用,包含一个显示数字的 TextBlock 和两个 Button(加/减)。
  2. 使用 MVVM 模式重构上述应用,将业务逻辑移到 ViewModel 中。
  3. 在 WebAssembly 平台运行你的应用,并尝试热重载功能。

(提示:Button 的 Command 属性可以绑定到 ViewModel 中的 ICommand)


参考资料

← 返回目录