wpf custom control
最近在做WPF,记录一下自定义控件的制作过程,源码请点击:源码。
1、目标
实现一个如图所示的可增减的数字框:
2、先画Template
可以在Generic.xaml中画,也可以用MergedDictionary连接到其他xaml中。
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/CustomControls;component/Themes/UpDownNumeric.xaml"/>
</ResourceDictionary.MergedDictionaries>
3、再实现UpDownNumeric
基类选择Control,也可以根据目标就近选择基类(比如ItemsControl、HeaderedContentControl之类的)。想好要暴露哪些属性、事件和命令,比如在这个例子里,只要暴露1个ValueProperty、2个CommandProperty(只贴增的,减类似不重复贴了)、和1个ValueChanged事件即可。
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(int), typeof(UpDownNumeric),
new PropertyMetadata(new PropertyChangedCallback(OnValueChanged)));
public static readonly DependencyProperty UpCommandProperty =
DependencyProperty.Register("UpCommand", typeof(ICommand), typeof(UpDownNumeric));
public static readonly RoutedEvent ValueChangedEvent =
EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<int>), typeof(UpDownNumeric));
再把这些属性包装成我们熟悉的.net的属性和事件,基于DelegateCommand实现命令、和触发ValueChanged的事件即可。
4、坑1:如果逻辑里的属性与控件的属性类型不匹配,要实现相应的IValueConverter
在这个例子里, 我把int型的Value绑定到TextBox的Text,int到string不能直接绑定,因此要实现一个Int2StringConverter,并在绑定时指定。否则不会显示值。
<TextBox Text="{TemplateBinding Value, Converter={StaticResource Int2StringConverter}}"/>
5、坑2:Image.Source的Pack Uri路径
这个路径如果没写对,要么编译不通过,要么虽然编译成功但运行的时候显示不出来。这里有几点关键:
5.1、右键图片->属性->生成操作->务必选择“资源”(Resource)
请不要选择“内容”或“嵌入的资源”,也不要将图片添加到“项目资源”中。“复制到输出目录”选择“不复制”。我分别尝试了这几种生成方式,如下:
资源:生成到.g.resources
内容:不生成到dll里
嵌入的资源:生成到Resources文件夹中,与.g.resources同级
项目资源:生成到*.Properties.Resources.resources
5.2、Pack Uri路径
网上到处是copy来的一大堆理论,看的晕。我试下来,在vs的Image.Source属性窗口里选,由vs自动生成的路径总是OK的,如下:
手动输入容易出错。只要生成为“资源”,下面3种写法都是正确的。
绝对路径:pack:///application:,,,/CustomControls;component/Resources/up.png
绝对路径-缩写版:/CustomControls;component/Resources/up.png
相对路径:../Resources/up.png
6、坑3:Template与控件Logic务必分离
这里的分离是指:Logic不应知道具体的控件名,Logic只暴露依赖属性(包括属性+命令),Template负责绑定属性。这种分离的好处是:如果用户不喜欢你的Template,自己再定制一个,只需绑定到同样的属性+命令,即可实现控件的行为。否则用户就无法改写Template了。
6.1、错误的实现方式
private Button upBtn;
public override void OnApplyTemplate(){
upBtn = (Button)this.Template.FindName("btnUp", this);
upBtn.Click = btn_Click;
}
这样写,就把Logic和Template绑死了。
6.2、正确的实现方式
//后台定义UpCommandProperty,实现为DelegateCommand或RoutedCommand,前台Template去绑定
public static readonly DependencyProperty UpCommandProperty =
DependencyProperty.Register("UpCommand", typeof(ICommand), typeof(UpDownNumeric));
<Button Command="{TemplateBinding UpCommand}"/>
wpf custom control的更多相关文章
- ClassLibary和WPF User Control LIbary和WPF Custom Control Libary的异同
说来惭愧,接触WPF这么长时间了,今天在写自定义控件时遇到一个问题:运行界面中并没有显示自定义控件,经调试发现原来没有加载Themes中的Generic.xaml. 可是为什么在其他solution中 ...
- Recommended Practices for WPF Custom Control Developers
I have always found that there isn’t enough documentation about Custom Control development in WPF. M ...
- [WPF] 将普通的Library工程,改造成WPF Custom Control 的Library
1. 添加References PresentationCore PresentationFramework System.Xaml WindowsBase2. 修改AssemblyInfo.xsus ...
- Hosting custom WPF calendar control in AX 2012
原作者: https://community.dynamics.com/ax/b/axilicious/archive/2013/05/20/hosting-custom-wpf-calendar-c ...
- Writing a Reusable Custom Control in WPF
In my previous post, I have already defined how you can inherit from an existing control and define ...
- WPF中的Generic.xaml, theme以及custom control
原文:WPF中的Generic.xaml, theme以及custom control 在Visual Studio中创建自定义控件时,所有控件都将添加到/Themes/Generic.xaml. 最 ...
- .NET Core学习笔记(2)—— WPF使用UWP Custom Control
自.NET Core 3.0开始,某软加入了对WPF的支持.同时对XAML Islands也做了进一步加强.在.NET Core 3.0之前,我们只能在WPF程序中,通过两种方式有限制地使用Stand ...
- Tutorial: WPF User Control for AX2012
原作者: https://community.dynamics.com/ax/b/goshoom/archive/2011/10/06/tutorial-wpf-user-control-for-ax ...
- WinForm中Component Class、User Control及Custom Control的区别和使用建议
reference: http://blog.csdn.net/redstonehe/article/details/1536549 .NET Framework 为您提供了开发和实现新控件的能力.除 ...
随机推荐
- 关于javascript的误区
JavaScript 误区 接触JavaScript两年多遇到过各种错误,其中有一些让人防不胜防,原来对JavaScript的误会如此之深,仅以此文总结一下常见的各种想当然的误区 String rep ...
- 【Todo】用python进行机器学习数据模拟及逻辑回归实验
参考了这个网页:http://blog.csdn.net/han_xiaoyang/article/details/49123419 数据用了 https://pan.baidu.com/s/1pKx ...
- 这个算asp.net的一个bug吗?
asp.net设置按钮Enabled="false"后OnClientClick中添加的验证脚本消失了 下面的确可以 <asp:Button ID="btnRegi ...
- sqlserver 2008 服务器拒绝连接;拒绝访问指定的数据库
sqlserver配置管理器----sqlserver网络配置 --- 启用 named pipes OK 由于之前的程序是SQL2000开发的,迁移到SQL20008出了这个问题. 二 和主题没有什 ...
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
Android 高手进阶(21) 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明地址:http://blog.csdn.net/xiaanming/article/detail ...
- MyBatis学习笔记(四) 注解
使用MyBatis注解开发,可以省去类配置文件,简洁方便.但是比较复杂的SQL和动态SQL还是建议书写类配置文件. 注解还是不推荐使用的.只是了解了解!简单的CRUD可以使用注解.简单写写. ...
- 利用SecureCRT上传、下载文件(使用sz与rz命令),超实用!
利用SecureCRT上传.下载文件(使用sz与rz命令),超实用! 文章来源:http://blog.csdn.net/dongqinliuzi/article/details/39623169 借 ...
- 合并Excel文件
//合并Excel文件 private void MargeExcelFile(string destFile, string dirPath) { DirectoryInfo dir = new D ...
- mysql数据库回滚
在应用$mysqli时,因没常用到数据回滚,老忘,整理下,做个记录. $mysqli->autocommit(FALSE);//自动提交设置关闭 $mysqli->query(" ...
- 使用Objective-C的文档生成工具
前言 做项目的人多了,就需要文档了.今天开始尝试写一些项目文档.但是就源代码来说,文档最好和源码在一起,这样更新起来更加方便和顺手.象Java语言本身就自带javadoc命令,可以从源码中抽取文档.今 ...