[WPF] UserControl vs CustomControl
介绍
WPF中有两种控件:UserControl和CustomControl,但是这两者有什么区别呢?这篇博客中将介绍两者之间的区别,这样可以在项目中合理的使用它们。
UserControl
- 将多个WPF控件(例如:TextBox,TextBlock,Button)进行组合成一个可复用的控件组;
- 由XAML和Code Behind代码组成;
- 不支持样式/模板重写;
- 继承自UserControl;
下面创建的一个RGBControl由3个TextBlock,3个TextBox,1个Rectangle组成。我们可以在WPF的任意窗体/Page上面复用该UserControl。
XAML Code:
<Grid Background="LightGray"><Grid.RowDefinitions><RowDefinition /><RowDefinition /><RowDefinition /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="*" /><ColumnDefinition Width="*" /><ColumnDefinition Width="2*" /></Grid.ColumnDefinitions><TextBlock Text="Red" /><TextBlock Text="Green" Grid.Row="1" /><TextBlock Text="Blue" Grid.Row="2" /><TextBox Text="{Binding Red, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Grid.Column="1" Height="25" Width="80" Margin="0,5" /><TextBox Text="{Binding Green, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1" Height="25" Width="80" Margin="0,5" /><TextBox Text="{Binding Blue, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Grid.Row="2" Grid.Column="1" Height="25" Width="80" Margin="0,5" /><Rectangle Fill="{Binding Color, Converter={StaticResource ColorToSolidBrushConverter}}" Grid.Column="2" Grid.RowSpan="3" Margin="10, 5" Width="100" Height="100"/> </Grid>
C# Code


public partial class RGBControl : UserControl {public RGBControl(){InitializeComponent();this.DataContext = new RGBViewModel();} }public class RGBViewModel : ObservableObject {private byte _red = 0;public byte Red{get{return _red;}set{if(_red != value){_red = value;RaisePropertyChanged("Red");RaiseColorChanged();}}}private byte _green = 0;public byte Green{get{return _green;}set{if(_green != value){_green = value;RaisePropertyChanged("Green");RaiseColorChanged();}}}private byte _blue = 0;public byte Blue{get{return _blue;}set{if(_blue != value){_blue = value;RaisePropertyChanged("Blue");RaiseColorChanged();}}}private Color _color;public Color Color{get{return _color;}set{RaiseColorChanged();}}private void RaiseColorChanged(){_color = Color.FromRgb(Red, Green, Blue);RaisePropertyChanged("Color");} }public class ObservableObject : INotifyPropertyChanged {public event PropertyChangedEventHandler PropertyChanged;protected virtual void RaisePropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));} }public class ColorToSolidBrushConverter : IValueConverter {public object Convert(object value, Type targetType, object parameter, CultureInfo culture){Color color = (Color)value;return new SolidColorBrush(color);}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){return null;} }
使用RGBControl:
<Grid><local:RGBControl Width="320" Height="120"/> </Grid>
CustomControl
- 自定义控件,扩展自一个已经存在的控件,并添加新的功能/特性;
- 由C#/VB.NET Code和样式文件组成(Themes/Generic.xaml);
- 支持样式/模板重写;
- 如果项目中自定义控件较多,建议创建一个WPF自定义控件库(WPF Control Library)
怎样创建一个WPF CustomControl呢?
选择合适的控件基类,或者说选择合适的控件进行功能扩展
UIElement 最轻量级的基类,支持Layout, Input, Focus, Event
FrameworkElement 继承自UIElement,支持styling,tooltips,context menus,data binding,resouce look up
Control 最基础的控件,支持template, 并增加了一些额外属性,例如Foreground, Background, FontSize等
ContentControl 在Control的基础上增加了Content属性,常见的控件有,布局控件,Button等
HeaderedContentControl 在ContentControl基础增加了一个Header属性,常见的控件有:Expander,TabControl,GroupBox等
ItemsControl 一个具有Items集合的控件,用来展示数据,但是不包含 Selection 特性
Selector 是一个ItemsControl,增加了Indexed,Selected特性,典型的控件有: ListBox, ComboBox, ListView, TabControl等
RangeBase 典型的控件有Sliders, ProgressBars. 增加了Value,Minimum和Maximum属性
WPF的控件行为和表现是分离的。行为在Code中定义,Template在XAML中定义。
重写Default Style
static NumericTextBox() {DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericTextBox), new FrameworkPropertyMetadata(typeof(NumericTextBox))); }
重写默认样式文件
<Style TargetType="{x:Type local:NumericTextBox}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:NumericTextBox}">...</ControlTemplate></Setter.Value></Setter> </Style>
以一个Numeric up/down控件为例:控件如下:
很直观的可以看到,Numeric up/down TextBox可以通过扩展WPF的TextBox控件实现,在WPF TextBox的基础上添加两个Button,然后重写这个自定义控件样式。
C# Code:
[TemplatePart(Name = UpButtonKey, Type = typeof(Button))] [TemplatePart(Name = DownButtonKey, Type = typeof(Button))] public class NumericTextBox : TextBox {private const string UpButtonKey = "PART_UpButton";private const string DownButtonKey = "PART_DownButton";private Button _btnUp = null;private Button _btnDown = null;static NumericTextBox(){DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericTextBox), new FrameworkPropertyMetadata(typeof(NumericTextBox)));}public override void OnApplyTemplate(){base.OnApplyTemplate();_btnUp = Template.FindName(UpButtonKey, this) as Button;_btnDown = Template.FindName(DownButtonKey, this) as Button;_btnUp.Click += delegate { Operate("+"); };_btnDown.Click += delegate { Operate("-"); };}private void Operate(string operation){int input = 0;if(int.TryParse(this.Text, out input)){if (operation == "+"){this.Text = (input + 1).ToString();}else{this.Text = (input - 1).ToString();}}} }
Style Code:
<Style TargetType="{x:Type local:NumericTextBox}"><Setter Property="SnapsToDevicePixels" Value="True" /><Setter Property="FontSize" Value="12" /><Setter Property="Height" Value="40" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:NumericTextBox}"><Border x:Name="OuterBorder" BorderBrush="LightGray" BorderThickness="1"><Grid><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="*" /><ColumnDefinition Width="30" /></Grid.ColumnDefinitions><Border Grid.ColumnSpan="2" Grid.RowSpan="2" Background="White"><ScrollViewer x:Name="PART_ContentHost" Margin="5,0" VerticalAlignment="Center" FontSize="12" /></Border><Button x:Name="PART_UpButton" Grid.Column="1" Content="+" VerticalContentAlignment="Center" /><Button x:Name="PART_DownButton" Grid.Row="1" Grid.Column="1" Content="-" VerticalContentAlignment="Center" /></Grid></Border></ControlTemplate></Setter.Value></Setter> </Style>
使用:
<StackPanel><custom:NumericTextBox Width="200" Text="1" /> </StackPanel>
感谢您的阅读~
参考文章:
https://wpftutorial.net/CustomVsUserControl.html
https://wpftutorial.net/HowToCreateACustomControl.html
相关文章:

50行Python代码,获取公众号全部文章
作者 | 胖虎转载自Python3X(ID: python3xxx )爬取公众号的方式常见的有两种:通过搜狗搜索去获取,缺点是只能获取最新的十条推送文章。通过微信公众号的素材管理,获取公众号文章。缺点是需要申请自己的公众号。今天介绍…

解决Windows7下vs2008 Active control test container 不能运行的问题
按照:http://blog.csdn.net/fengbingchun/archive/2011/05/05/6398356.aspx 在windows7系统中,vs2008环境下用MFC ActiveX Control生成的控件不能正常编译,但是在xp系统中却能正常编译,解决方法: 1、在windows7中编译…

入门必备 | 一文读懂神经架构搜索
作者 | Md Ashiqur Rahman编译 | 刘静转载自图灵TOPIA(ID: turingtopia)近期谷歌大脑团队发布了一项新研究:只靠神经网络架构搜索出的网络,不训练,不调参,就能直接执行任务。这样的网络叫做WANN,…

脚本化 tmux — LinuxTOY
脚本化 tmux — LinuxTOY脚本化 tmux2012-07-02 Toy Posted in TipsRSS昨天我在家试了下脚本化 tmux,其表现相当令人满意,只需稍加定制便可满足各种实际需要。这或许可以成为抛弃 GNU screen,改用 tmux 的又一个理由。该脚本先判断一个名为 c…

OpenCV像素点处理
转自:http://blog.csdn.net/hxgqh/archive/2011/02/23/6202001.aspx 获得像素点的值便可以更加灵活的进行图像处理,在OpenCV里可以通过cvGet2D()和cvSet2D()两个函数加上一个CvScalar结构体做到。OpenCV中,CvScalar结构为:typedef…

亲 , Zookeeper了解一下 : 概述
2019独角兽企业重金招聘Python工程师标准>>> 在学习的过程中,我们总需要一个来自灵魂的拷问: 为什么? 为什么会产生Zookeeper 这个问题有深度,那要从五百万年说起,在遥远的塞伯坦星球..... 扯远了... 在遥远在单机单服务的时代 , 想要扩展服务 , 只能增加硬件配置 …

wordpress jquery加载如何实现?
2019独角兽企业重金招聘Python工程师标准>>> 为什么写这篇文章? 因为之前在wordpress里面用jquery的时候没注意,这次因为要优化网站把没用的插件删了,结果发现有的jquery功能失效了,调试了许久才发现可能是jQuery没有定…

百度与华为重磅合作!李彦宏:技术是百度的信仰
导语:这是百度第三年举办AI开发者大会。一生二,二生三,三生万物。AI虽然不能产生万物,但是正在“唤醒万物”。 作者 | 阿司匹林 出品 | AI科技大本营(ID:rgznai100) 在今天上午举行的的百度AI开发者大…

已知空间一点到另外两点直线的距离
转自:http://www.cnblogs.com/clarkustb/archive/2008/11/04/1326500.html 已知空间一点到另外两点直线的距离设空间中的三点为M1,M2,M3,分别用矢量a,b表示方向向量M1M2和M1M3,则: 1. M3到M1,M2连线的距离为|axb|/|a|,这里|.|表示向量的…

vue---进行post和get请求
参考文档: https://www.jb51.net/article/125717.htm 使用axios <script src"https://unpkg.com/axios/dist/axios.min.js"></script> 基本使用方法: get请求: // Make a request for a user with a given ID axios.ge…

CxImage图像处理类库
转自:http://blog.csdn.net/byxdaz/archive/2009/04/10/4061324.aspx CxImage是一个可以用于MFC 的C图像处理类库类,它可以打开,保存,显示,转换各种常见格式的图像文件,比如BMP, JPEG, GIF, PNG, TIFF, MNG…

设计模式学习2 工厂模式
工厂模式其实就是简单模式的升级版本, 简单模式将界面与业务逻辑区分开,但是如果不停的增加计算器的运算方式,简单模式中的工厂Factory 中判断的业务逻辑会变非常复杂,这不符合封装的原则。 所以在此之上将Factory抽象了出来&…

输入字符串,包含数字,大小写字母,编程输出出现做多的数字的和
题目描述: 输入字符串,包含数字,大小写字母,编程输出出现做多的数字的和。 思路: 1.创建输入对象2.输入字符串3.利用正则将字母分离出,剩余的每一个字符串即为待统计的每一个数字,存入字符串数组…

优化思路千万种,基于下界函数的最优化效率如何?
作者丨stephenDC来源 | 大数据与人工智能(ID:ai-big-data)导读:生活中我们处处面临最优化的问题,比如,怎么样一个月减掉的体重最高?怎么样学习效率最高?怎么样可以最大化实现个人价值࿱…

Quintum 语音网关设置方法
Quintum 网关基本配置 Quintum 网关基本配置 登陆方式:方法一:串口登陆(1).用配套的串口线连接网关的CONSOLE口和电脑的串口。 (2).开启电脑的的超级终端,路径如下&#…

Activex test contact failed to create control 未指定的错误 控件无法加载的原因
转自:http://blog.csdn.net/phker/archive/2009/12/25/5073402.aspx 本文指的是vc项目的activex 出现这个问题, 我总结了总共有以下几点,可能还有其他原因: 1.中文问题:如果你的项目类型是多字节的,而不是unicode编码的,你可能要注意这个问题了,我就发生了这个问题…

人工智能技术在内容行业的应用:AI对中长尾内容平台还是奢侈品
整理 | 夕颜出品 | AI科技大本营(ID:rgznai100)导读:随着人工智能技术的发展,媒体行业本身在不断地发生变化,从传统媒体到新媒体,改变的不仅是信息载体,更是一种新的逻辑,无论是内容…

QQ爬虫-爬取QQ空间
背景:在一篇个人博客看到了相关的爬虫的知识,个人比较有兴趣,就花了点时间研究了一下,主要通过好友空间的互动(相互访问量,点赞,评论,以及其他互动),以及好友之间聊天的活跃度&#…

perl编程手册
2019独角兽企业重金招聘Python工程师标准>>> perl编程手册: -------------------------------手册-------------------------------- perl手册.chm http://vdisk.weibo.com/s/moN-p -------------------------------视频-------------------------------- 俺的…

VC使用ActiveX控件常见问题
转自:http://lingchuangsong.blog.163.com/blog/static/126932322008631104133309/ 一方面,它表示将你联系到Microsoft、Internet和业界的新技术的小型快速的可重用组件。它与开发语言无关,任何支持 ActiveX控件的软件开发平台(如…

你绝没用过的一款高级空间可视化工具
作者 | Shan He转载自高级农民工(ID: Mocun6)说起 Python 中的可视化,我们一般用的最多的是 Matplotlib,绘制一般的图效果都很好。有时候也会用风格比较好看的 Pyecharts 库,尤其是在展示空间地图上的数据时。不过它的…

揭秘vue——vue-cli3全面配置
★ vue-cli3 全面配置 ★ Nuxt.js 全面配置 创建项目 配置环境变量 通过在package.json里的scripts配置项中添加--mode xxx来选择不同环境 在项目根目录中新建.env, .env.production, .env.analyz等文件 只有以 VUE_APP_ 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端…

周礼栋:现在是计算机系统和网络研究“最好的时代”
编者按:随时随地使用各种系统和工具,对现代人来说早已是司空见惯的事,但这一切完美工作的技术和服务并不是凭空出现的。正是因为微软亚洲研究院副院长周礼栋博士和他带领的团队这样从事系统和网络研究工作的研发人员在幕后不断的努力和创新&a…

ChaLearn Gesture Challenge_2:examples体验
前言: 在上一篇博文ChaLearn Gesture Challenge_1:CGD数据库简单介绍中已经简单介绍过CGD2011数据库,了解到该数据库可以作为公开的数据库来测试在深度信息和RGB信息上的手势识别。当然了,也可以通过参加这个挑战赛来对比自己的手…

vs2008 外部调用ActiveX控件接口方法
转自:http://topic.csdn.net/u/20090605/16/018e26e9-06e2-4e0d-8099-bc8eb326afde.html sndaxdrs: 初学activeX ,我写的一个 activeX控件测试程序。 分别调用两个 自定义方法, 分别出现 “找不到成员”,和“非选择性的参数”的提…

设计模式之禅笔记
2019独角兽企业重金招聘Python工程师标准>>> 1.设计原则 1)单一职责原则 There should never be more than one reason for a class to change (就一个类而言,应该只有一个引起它变化的原因) 用于控制类的粒度大小,防止类过于复杂…

vs2008部署问题
转自:http://tangxingqt.blog.163.com/blog/static/2771087220098214755269/ 参考资料 1、VS2005解决"应用程序配置不正确,程序无法启动"问题 2、VS2005安装文件 "由于应用程序配置不正确,应用程序未能启动" 3、Micro…

expdp数据泵导出操作
数据泵需要在本地执行,不可以远程登录操作。 数据泵需要建立目录directory --sys下 create directory su as d:\xs 目录的数据字典是dba_directories SYSncbeta>select owner,directory_name,directory_path from dba_directories; 要求导出scott用户下的emp表…
slf4j 日志监控
问题描述 监控系统 新系统起步,旨在监控原有系统的各种问题。主要的一部分,就是监视原有系统的日志。 日志,是Java企业级应用开发必不可少的一部分,市场上有诸多日志框架。我们选用slf4j。 日志有以下级别: TRACE, DEB…

阿里90后科学家研发,达摩院开源新一代AI算法模型
整理 | 一一出品 | AI科技大本营(ID:rgznai100)AI科技大本营7月5日消息,阿里达摩院宣布开源新一代人机对话模型ESIM。该算法模型提出两年多,已被200多篇论文引用,更曾在国际顶级对话系统评测大赛(DSTC7&…