WindowsCommunityToolkit3.0无限画布新体验
Windows Community Toolkit 3.0 推出了强大的InfiniteCanvas控件,支持无限画布滚动、墨迹书写、文本输入、格式化文本、画布缩放、撤销重做以及数据导入导出功能。这一控件在“来画视频”UWP应用中得到了实际应用,提供了丰富的绘画工具选择,如不同画笔、橡皮擦、直尺和圆形尺,并支持文字输入和字体选择,方便用户创作并分享绘画作品。InfiniteCanvas的代码结构清晰,包括命令、控件、绘制功能和事件处理等模块,开发者可以通过示例代码和文档进一步了解其实现细节。
概述
InfiniteCanvas 是一个 Canvas 控件,它支持无限画布的滚动,支持 Ink,文本,格式文本,画布缩放操作,撤销重做操作,导入和导出数据。
这是一个非常实用的控件,在“来画视频” UWP 应用的绘画功能中,也用到了这个控件,它对不同画笔的选择,橡皮擦,直尺和圆形尺,文字输入和字体选择等都提供了很便捷的支持,而且支持导入和导出数据,可以很方便的创作绘画作品,并能导出和分享给别人。
下面是 Windows Community Toolkit Sample App 的示例截图和 code/doc 地址:

Windows Community Toolkit Doc - InfiniteCanvas
Windows Community Toolkit Source Code - InfiniteCanvas
Namespace: Microsoft.Toolkit.Uwp.UI.Controls; Nuget: Microsoft.Toolkit.Uwp.UI.Controls;
开发过程
代码结构分析
首先来看 InfiniteCanvas 的代码结构,组成如下:
Commands - InfiniteCanvas 对应的所有命令,包括 redo/undo,Ink,Text 等,如上面示例图中 Toolbar 上所示;Controls - InfiniteCanvas 的主要控件都在这个文件夹里;Drawables - Text 和 Ink 主要的绘制功能在这个文件夹里;JsonConverters - 序列化和反序列化的主要功能,以及自定义的 Ink 属性等;InfiniteCanvas.Events.cs - InfiniteCanvas 的主要事件处理逻辑;InfiniteCanvas.TextBox.cs - InfiniteCanvas 添加文字的文本框控件处理逻辑;InfiniteCanvas.cs - InfiniteCanvas 控件的主要处理逻辑;InfiniteCanvas.xaml - InfiniteCanvas 控件的 XAML 样式文件;
InfiniteCanvas 整体类结构很清晰,每个类的功能也很明确,下面我们选取几个重要的类来做分析。
1. InfiniteCanvasCreateInkCommand
Command 文件夹的每一个类都比较简单,我们找一个创建 Ink 命令看一下;该类实现了 IInfiniteCanvasCommand 这个接口,实现了 Execute() 和 Undo() 两个方法;Command 初始化也很简单,创建一个 InkDrawable 对象,初始化 drawableList 对象,执行创建时加入该 drawable,撤销时把它从 drawableList 中去掉。
代码语言:javascript代码运行次数:0运行复制internal class InfiniteCanvasCreateInkCommand : IInfiniteCanvasCommand{ private readonly List _drawableList; private readonly InkDrawable _drawable; public InfiniteCanvasCreateInkCommand(List drawableList, IReadOnlyList strokes) { _drawable = new InkDrawable(strokes); _drawableList = drawableList; } public void Execute() { _drawableList.Add(_drawable); } public void Undo() { _drawableList.Remove(_drawable); }} 2. InfiniteCanvasTextBox
用于 InfiniteCanvas 的文本框控件,从下图的结构中可以看到完整的文本框属性定义方法,包括设置文字,设置编辑区域尺寸,文字变化的处理,光标位置的限制等。

来看一下判断光标能够下移一行的 CannotGoDown() 方法,按照换行符来切割文字行,如果只有一行则不可下移;当前选择的结束,在最后一行时,也不可下移,其他情况都可以下移;
代码语言:javascript代码运行次数:0运行复制internal bool CannotGoDown(){ var lines = _editZone.Text.Split('\r'); if (lines.Count() == 1) { return true; } var lastLine = lines.ElementAt(lines.Length - 1); if ((_editZone.Text.Length - lastLine.Length) 3. InfiniteCanvasVirtualDrawingSurface
用于渲染 Ink 和 Text 的虚拟 drawing surface,它有几个部分类组成:

主要的处理逻辑,是利用 Commands 来操作 Ink 和 Text 的渲染执行和撤销操作,计算渲染的尺寸空间,组织渲染的内容。
4. InkDrawable 和 TextDrawable
Ink 和 Text 可绘画元素的绘画逻辑,分别来看一下两个类的组成:


我们看一下两个类的 Draw 方法:
Draw() - InkDrawable:
获得 Strokes 中每个线条的每个点,加入到集合中,从点集合创建线条,最后生成新的 Stroke 列表;遍历完成后,把新的 Stroke 列表用于 drawingSession 的 DrawInk 方法来实现绘制;
代码语言:javascript代码运行次数:0运行复制public void Draw(CanvasDrawingSession drawingSession, Rect sessionBounds){ var finalStrokeList = new List(Strokes.Count); foreach (var stroke in Strokes) { var points = stroke.GetInkPoints(); var finalPointList = new List(points.Count); foreach (var point in points) { finalPointList.Add(MapPointToToSessionBounds(point, sessionBounds)); } StrokeBuilder.SetDefaultDrawingAttributes(stroke.DrawingAttributes); var newStroke = StrokeBuilder.CreateStrokeFromInkPoints(finalPointList, stroke.PointTransform); finalStrokeList.Add(newStroke); } drawingSession.DrawInk(finalStrokeList);} Draw() - TextDrawble:
设置 Canvas 中文本的格式,使用文本和格式设置的 textLayout 来用于 drawingSession 的 DrawTextLayout 方法实现绘制;根据字体大小设置横向偏移 HorizontalMarginBasedOnFont,固定的纵向偏移 verticalMargin;
代码语言:javascript代码运行次数:0运行复制public void Draw(CanvasDrawingSession drawingSession, Rect sessionBounds){ const int verticalMargin = 3; CanvasTextFormat format = new CanvasTextFormat { FontSize = FontSize, WordWrapping = CanvasWordWrapping.NoWrap, FontWeight = IsBold ? FontWeights.Bold : FontWeights.Normal, FontStyle = IsItalic ? FontStyle.Italic : FontStyle.Normal }; CanvasTextLayout textLayout = new CanvasTextLayout(drawingSession, Text, format, 0.0f, 0.0f); drawingSession.DrawTextLayout(textLayout, (float)(Bounds.X - sessionBounds.X + HorizontalMarginBasedOnFont), (float)(Bounds.Y - sessionBounds.Y + verticalMargin), TextColor);} 5. InfiniteCanvas
InfiniteCanvas 是主要逻辑处理,由 InfiniteCanvas.cs,InfiniteCanvas.Events.cs,InfiniteCanvas.TextBox.cs 三个部分类组成。
其中 InfiniteCanvas.cs 这个类中主要是实现 OnApplyTemplate(),DependencyProperty 处理,控件的定义,事件注册,Canvas 的基础事件处理等,InfiniteCanvas 中实现了一个 InkCanvas 所以可以实现各种笔触的笔迹绘制;InfiniteCanvas.Events.cs 主要是 Canvas 中的各种按钮点击等事件处理;InfiniteCanvas.TextBox.cs 主要是 Canvas 中 TextBox 控件对应的控件定义和事件处理;调用示例
InfiniteCanvas 控件的调用非常简单,下面看看 XAML 中的调用:
代码语言:javascript代码运行次数:0运行复制总结
到这里我们就把 Windows Community Toolkit 3.0 中的 InfiniteCanvas 的源代码实现过程讲解完成了,希望能对大家更好的理解和使用这个功能有所帮助。InfiniteCanvas 控件在绘画类场景中有非常多的应用,控件默认实现了多种笔触的绘画,橡皮,文字,redo undo 等重要功能,开发者也可以根据 InfiniteCanvas 的实现自定义 Toolbar 的样式和更多的绘画笔触,不同的笔画保存方式等。
最后,再跟大家安利一下 WindowsCommunityToolkit 的官方微博:https://weibo.com/u/6506046490, 大家可以通过微博关注最新动态。
衷心感谢 WindowsCommunityToolkit 的作者们杰出的工作,感谢每一位贡献者,Thank you so much, ALL WindowsCommunityToolkit AUTHORS !!!
文中关于绘画工具,代码结构,墨迹书写,InfiniteCanvas,文本输入的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《WindowsCommunityToolkit3.0无限画布新体验》文章吧,也可关注golang学习网公众号了解相关技术文章。
PHP中|运算符使用技巧与示例
- 上一篇
- PHP中|运算符使用技巧与示例
- 下一篇
- Jpgraph3.5中文乱码终极解决方案
-
- 文章 · 软件教程 | 56分钟前 | 环境变量 · docker compose · 容器配置 · 环境变量 Docker Compose Environment env_file
- Docker Compose区分 env_file 与 environment 覆盖关系的实现方法
- 336浏览 收藏
-
- 文章 · 软件教程 | 1小时前 | 软件教程 · 视频生产协作 · MCN运营实操 · 内容团队管理 · 项目交接规范 · MCN栏目视频交接方法 LibTV内容交付流程 视频审核回执整理规范 视频版本台账搭建 栏目复用模板制作指南
- MCN用LibTV做完栏目视频后怎么交接?整理审核回执、版本台账和复用模板
- 385浏览 收藏
-
- 文章 · 软件教程 | 1小时前 | MCN内容生产 · LibTV教程 · 短视频制作 · 内容审核流程 · 创作者工具 · MCN用LibTV跑通内容 LibTV选题卡填写方法 LibTV镜头表制作规范 LibTV三关口审核流程 短视频内容生产实操教程
- MCN第一次用LibTV怎么跑通一条内容?从选题卡、镜头表到审核回传
- 304浏览 收藏
-
- 文章 · 软件教程 | 2小时前 | LibTV教程 · 影视团队协作 · AI视频交付 · 项目归档管理 · 视频后期实操 · LibTV专业视频交付方法 LibTV成片复核步骤 AI视频项目素材归档规范 专业视频交付修改说明指南 视频项目交付清单制作技巧
- LibTV做完专业视频后怎么交付?从成片复核、素材归档到修改说明
- 327浏览 收藏
-
- 文章 · 软件教程 | 2小时前 | 开发工具 · vs code · 调试配置 · VS Code launch.json Compound 多目标调试
- VS Code 调试用 Compound 同时启动多个调试目标的实现方法
- 351浏览 收藏
-
- 文章 · 软件教程 | 2小时前 | AI视频创作 · LibTV教程 · 短片制作全流程 · 影视团队协作 · 视频项目管理 · LibTV完整短片制作教程 专业视频创作者AI短片工作流 LibTV镜头清单制作方法 AI生成短片交付复盘步骤 智能台灯宣传短片制作案例
- 专业视频创作者第一次用LibTV怎么做完整短片?从镜头清单到交付复盘
- 356浏览 收藏
-
- 文章 · 软件教程 | 3小时前 | 需求管理 · 墨刀教程 · 产品工具 · AI原型制作 · UI原型实操 · 墨刀AI原型需求对齐 AI生成UI原型排查方法 AI原型页面状态校验 UI原型改稿范围控制 墨刀AI实用技巧
- 墨刀AI做UI原型偏离需求怎么办?从输入约束、页面状态到改稿范围排查
- 241浏览 收藏
-
- 文章 · 软件教程 | 3小时前 | vs code · tasks.json · 输入变量 ·
- VS Code tasks为任务配置可复用输入变量的实现方法
- 500浏览 收藏
-
- 文章 · 软件教程 | 3小时前 | 墨刀AI · 产品工具教程 · UI原型制作 · 产品原型入门 · 原型评审规范 · 墨刀AI新手做UI原型 墨刀AI原型制作完整步骤 设备巡检UI原型教程 墨刀AI页面清单制作 UI原型状态走查方法
- 墨刀AI新手如何做第一套UI原型?从页面清单到状态走查的完整步骤
- 485浏览 收藏
-
- 文章 · 软件教程 | 4小时前 | 墨刀AI · 研发协作 · PRD编写 · 产品工具教程 · 需求文档优化 · 墨刀AI需求文档补全 空泛PRD修正方法 产品经理PRD编写技巧 需求验收条件设置 业务规则梳理方法
- 墨刀AI生成的需求文档太空泛怎么办?从证据、业务规则和验收条件补齐内容
- 425浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 43次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 140次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 75次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 43次使用
-
- CMMLU
- 深入了解CMMLU中文评估基准,涵盖67个学科主题,提供数据集下载、Zero-shot/Five-shot评估方法及排行榜,助力优化中文语言模型性能。
- 27次使用
-
- VS Code 怎么给 Go 项目配置测试任务:tasks.json 运行与结果验收
- 2026-07-09 501浏览
-
- Windows 11 如何开启 HEIF 图片支持
- 2026-05-31 501浏览
-
- TikTok用户画像与付费订阅变现方法
- 2026-05-27 501浏览
-
- 学信网学历翻译件申请方法
- 2026-05-27 501浏览
-
- Windows 11 24H2 更新失败0x80070005解决方法
- 2026-05-26 501浏览

