在上一篇入门踩坑指南中,我们爬出了几个关于使用变量的undocumented feature坑。
JustForFun:微软Canvas App实战踩坑指南——undocumented featurezhuanlan.zhihu.com但是你需要知道的一件重要事情是,在Canvas app中,像常规开发那样去使用变量并不是正确的姿势。也就是篇尾我提到的,这东西思路上更接近Excel的一个情况。
本文描述了使用Canvas App变量和事件的正确姿势,全文1700字,需要10分钟。说不定读完之后你的入门困扰就没了呢!
首先我们用一个简单的数据绑定来热个身。
当我们试图在画布中间摆放一个按钮的时候,你会怎么做?拖拉拽嘛,很简单对不对?
那么,如果你需要在一个容器的中间摆放控件呢?复杂的相互对齐怎么拖放呢?控件直接堆叠覆盖不便拖拽的时候怎么办呢?
这时候我们可以选中使用属性面板或者表达式栏,将一个示例按钮的X值设置为一个表达式,其值为父容器的宽度减去控件自己的宽度。这样,无论父容器发生什么改变,这个示例按钮永远都会“停靠”在其父容器的右侧了。那么具中摆放是不是也顺理成章了呢?只需要将表达式改为 Parent.Width/2-Button6.Width/2 不就会具中“停靠”了嘛!是不是很简单?
在这个示例中,Button6是按钮的名字,当代表自身出现的时候也可以使用Self关键字替代。
但是需要注意,如果你再次对这个控件进行拖拽操作的话,表达式会被重置为你拖拽摆放的数值常量。不过这个使用表达式绑定控件属性的手法是万变不离其宗的,比如我们可以对 Visible (可见/隐藏)属性绑定一个全局变量,或者将X、Y设置为与上一个控件相关,于是就有了“相对位置”的效果。
事件驱动?
热身完毕,我们来做一个常规开发中最简单的界面操作。下图中的三个文本框接受用户输入的数,比较其最大值,显示在右侧的Label里输出。当然,实际的业务场景可能是下拉框、单选框之类的复杂运算逻辑,我们的最大值运算只是一个简化的演示。
公式写起来是一个嵌套的表达式,将文本框的值逐个转换为数字类型,使用max函数进行比较后赋值给变量 X。我们将这段公式赋值,粘贴到三个文本框的OnChange里面。然后就会在每个文本框发生改变时触发计算刷新X的值。
这个示例为了简化并没有处理数字类型转换出错的情况。实际的代码写出来会稍微有一点长,而且函数的嵌套会导致缩进不便阅读。所以我们更需要减少复制粘贴的次数以免把自己弄得焦头烂额。
然后对Label的文本属性赋值比较简单,直接写上Text等于X就好。运行效果一望可知。
但是大家会发现,这样做虽然不难,但是一旦公式写错了需要修改,或者业务变更了需要修改公式,这个过程就变得不那么舒服了。毕竟这个在线编辑器没有查找替换,你可能已经忘记在哪几处地方设置过事件了(甚至有可能你接手了别人的app继续开发,根本不知道哪里做了事件处理)
正确姿势:数据绑定
下面我们尝试做一点点小修改。删除上面所有的公式,只保留控件,我们从头来过!
你将不再需要事件,甚至也不需要变量X,只需要在目标Lable上这样写一个赋值公式就可以了。运行效果和上面一种事件驱动的做法一摸一样,但是思路是不是清晰了很多,代码缩进也减少了,对吧!
如果熟悉前端MVVM开发的话,应该很容易看出,这个其实就是MVVM中的双向绑定。如果熟悉Excel公式的话,你也很容易发现,这个跟Excel单元格计算公式如出一辙,区别仅仅是控件比单元格更具交互性。
而且这个Label上显示的计算结果还可以被其它控件中的公式所引用,就像你用Excel表格做了汇总,再用汇总值去做饼图一样,当你修改一处单元格时,汇总值和饼图都会随之改变。你所需要小心的仅仅只是不要写出了循环依赖的表达式就好。即使写出来了也没关系,编辑器会报错的。
这个就是我上次为什么说,表哥表妹们可能会更擅长Canvas App开发的缘故了。如果是程序猿第一次做的时候可能会需要先了解一下MVVM开发模式,否则写出前面一种东西来,维护的时候会想哭的!
更多学习心得、笔记资料传送门
TiDB源码学习笔记:
TiDB源码学习笔记:启动TiDB - 知乎 (zhihu.com)
TiDB源码学习笔记:SQL的一生 - 知乎 (zhihu.com)
PowerApps实战指南:
微软Canvas App实战踩坑指南——事件驱动 or 数据绑定 - 知乎 (zhihu.com)
微软Canvas App实战踩坑指南——undocumented feature - 知乎 (zhihu.com)