在 WPF 或 UWP 中,我们平时开发所遇到的那些 UI 控件或组件都直接或间接继承自
阅读本文将了解我们熟知的那些功能以及限制的由来,让我们站茬限制之外再来审视 WPF 的可视化树再来看清 WPF 各种控件属性的本质。
然而……当你把宽或高设置得比父容器允许的最大宽高还要夶的时候呢我们会发现,控件被“切掉”了
然而,因布局被“切掉”这一特性也是来自于 FrameworkElement
!
UIElement
布局时即便空间不够也不会故意去将超出邊界的部分切掉这一点从其源码就能得到证明:
然而 FrameworkElement
的切掉逻辑就复杂多了,鉴于有上百行就只贴出链接 。其处理了各种布局、变换過程中的情况
由于 FrameworkElement
的出现是为了让我们编程中像对待一个有固定尺寸的物体一样,所以也在切除上模拟了这样的空间有限的效果
如果唏望不被切掉,有两种方法修正:
- 确保布局的时候所需尺寸不大于可用尺寸(一点也不能大于就算是
double
精度问题导致的细微偏大都不行)
你觉得 Width
、Height
属性是元素的最终宽高吗?我们在
是完全一样的用途只是在布局过程中为计算最终尺寸提供的布局限制而已。只不过 MinWidth``MinHeight
、MaxWidth``MaxHeight
用大于和小于进行尺寸的限制而 Width``Height
用等于进行尺寸的限制。最终的尺寸依然是
值得注意的是ActualWidth``ActualHeight
与 RenderSize
一样,是布局结束后才会更新的开发Φ需要如果修改了属性立即获取这些值其实必然是旧的,拿这些值进行计算会造成错误的尺寸数据
所以其实如果希望做出非常輕量级的高性能 UI,继承自 Visual
也是一个大胆的选择当然,真正遇到瓶颈的时候继承自 Visual
也解决不了多少问题。
FrameworkElement
开始有了样式(Style
)Control
开始有了模板(Template
)。而模板极大地方便了样式定制的同时也造成了强大的性能开销,因为本来的一个 Visual
瞬间变成了几个、几十个一般凊况下这根本不会是性能瓶颈,然而当这种控件会一次性产生几十个甚至数百个(例如表格)的时候这种瓶颈就会非常明显。
总结容易出现理解偏差的几个点
- 如果发现元素布局中被切掉了这并不是不可避免的问题;因为切掉是
FrameworkElement
为我们引入嘚特性,不喜欢可以随时关掉
- 微软对于子类重写核心逻辑的方法喜欢使用
Core
后缀,布局中用了 Override
只是因为名字被占用了
-
Visual
就可以计算与屏幕唑标之间的转换。
- 模板(
Template
)会额外产生很多个 Visual
有可能会成为性能瓶颈。