WPF 用户控件分享之边上带输入框的圆圈
独立观察员 2022 年 8 月 20 日
最近有这样一个需求,有一圈圆形,每个圆形边上有个输入框,以下是完成后的效果图:
拿到这个需求后,分析界面上每个圆形和输入框应该视为一个用户控件,且输入框相对于圆形的位置不是一致的,所以应该要能够通过一个属性来设置输入框的位置。那么就以这个为突破口,创建一个用户控件,在代码隐藏页中添加一个用于控制输入框位置的依赖属性 “TextBoxPlacement”:
【题外话]】添加依赖属性的方法为,输入 “propdp” 然后按 Tab 键(也就是使用官方提供的代码片段),然后修改类型、修改名称、修改所属类、修改默认值,如下:
继续说回 TextBoxPlacement 属性,我给它的类型是 PlacementMode,这是借用的 Popup 控件的方位属性:
这是个枚举,有很多取值情况,本次只是用到了它的子集(上下左右):
好了,控制位置的属性有了,那么怎么动态切换呢?别急,我们先来看看整个用户控件的界面布局:
可以看到,界面上就只有一个 Control 元素,给它设置了一个样式,将在该样式中使用 DataTrigger(数据触发器)来切换不同的控件模板,从而改变布局。最开始想用数据模板选择器的,后来发现那个应该是适用于列表控件中依据数据不同从而动态选择子项的模板的情况,不适用于这种用户控件中。
最重要的就是给 Control 设置的样式 “CircleWithTextBoxStyle”:
上下左右这四种情况都是通过设置 Control 的 Template 的属性(具体是控件模板 ControlTemplate)来实现不同的布局的。默认是输入框在圆圈右边的布局,其余的 左、上、下 则是通过数据触发器 DataTrigger 来实现的,数据触发器绑定 UserControl 的 TextBoxPlacement 属性(前面我们添加的那个),依据不同的值来切换不同的控件模板。至于四种情况的布局实现,容器都是 StackPanel,左和右的时候是横向的,上和下的时候是纵向的;左和上的时候输入框部分写在前面,右和下的时候输入框部分写在后面。
圆圈和输入框部分也分别是一个 Control 元素,通过样式设置模板,样式如下:
圆圈就是一个 Border,使用样式 BorderStyle。圈内文本是一个 TextBlock,使用样式 InfoStyle,文本内容绑定了一个依赖属性 CircleInfo。输入框就是一个 TextBox,使用样式 TextBoxStyle。
先来看看圆圈内文本样式,涉及两个依赖属性,一个是文字颜色属性 CircleForeground,另一个是文字大小属性 InfoFontSize(输入框也是用这个设置文字大小的),具体如下:
然后是圆圈和输入框的样式,涉及圆圈边框色属性 CircleBorderBackground,圆圈背景色属性 CircleBackground,圆圈直径和输入框宽度的共用属性 CircleAndTextBoxWidth,以及输入框的值属性 TextBoxValue:
【题外话]】此处用到了一个叫做 CalcBinding 的库,可以绑定表达式,这样就省去了转换器,感兴趣的朋友可以自己搜索研究一下。
比如,此处的圆圈,是用宽高相等的 Border,然后圆角 CornerRadius 设为宽高的一半,直接绑定为 'Width / 2' 即可,十分方便。再比如,输入框和圆圈等宽,高度为宽度的五分之三,直接绑定 'Width * 3 / 5' 即可。
后面提到的依赖属性如下:
好了,整个用户控件都讲完了,那么如何使用呢?很简单,直接放在界面上,然后设置需要的依赖属性即可(此 Demo 源码地址文末会给出):
开局那幅图(一整圈)的布局也可以浅看一下:
其实也是分为上下左右四部分,通过 ItemsControl 来绑定数据,然后在数据模板中使用本文介绍的用户控件,样式如下,一些属性进行了设置和绑定:
由于界面上的编号不是按布局的顺序来的,所以初始化时做了些处理:
Demo 源码地址(子模块中有用户控件源码):
https://gitee.com/dlgcy/DLGCY_WPFPractice/tree/Blog20220820
全文完,感谢阅读!
WPF
分享一个 WPF 气泡弹框
WPF 表单验证之 INotifyDataErrorlnfo 接口的使用示例
[翻译] WPF 中用户控件 DataContext/Binding 和依赖属性的问题
OxyPlot 导出图片及 WPF 元素导出为图片的方法
让 WPF 的 RadioButton 支持再次点击取消选中的功能
WPF DataGrid 如何将被选中行带到视野中
WPF 触屏事件后触发鼠标事件的问题及 DataGrid 误触问题
WPF DataGrid 通过自定义表头模拟首行固定
WPF ComboBox 使用 ResourceBinding 动态绑定资源键并支持语言切换
【翻译】WPF 中附加行为的介绍 Introduction to Attached Behaviors in WPF
WPF 使用 Expression Design 画图导出及使用 Path 画图
WPF MVVM 弹框之等待框
解决 WPF 绑定集合后数据变动界面却不更新的问题(使用 ObservableCollection)
WPF 消息框 TextBox 绑定新数据时让光标和滚动条跳到最下面
真・WPF 按钮拖动和调整大小
WPF MVVM 模式下的弹窗
WPF 让一组 Button 实现 RadioButton 的当前样式效果
WPF 原生绑定和命令功能使用指南
WPF 用户控件的自定义依赖属性在 MVVM 模式下的使用备忘
在WPF的MVVM模式中使用OCX组件
第三方库使用
WPF 表格控件 ReoGrid 的简单使用
OxyPlot.WPF 公共属性一览
OxyPlot.Wpf 图表控件使用备忘