WPF 定义自己的控件
来源:互联网 发布:西安软件学校 编辑:程序博客网 时间:2024/04/30 13:32
最近在研究怎么制作自己的控件,制作好了之后给别人用,别人只需要修改控件的相关属性就可以适应他的需求,而无需去修改控件的模板。先上图再解释。
以下是我自己制作的控件截图:
温度计:
模拟微信文章后面的摆球:
由于是摆动的,截图看效果不明显,下载源码看
以下是我借鉴别人的加以改进的控件
进度条:
win8转圈等待控件:
以下是纯别人写的
油表:
转圈等待:(这个控件是Winform的,也可以用到WPF)
最后再晒一张将控件用在项目中的图片的效果:
本文所有控件打包下载地址
自定义控件的过程:
1.新建一个WPF custom control library:
2.新建成功后,会自动生成一个类(.cs)文件和一个资源字典(Generic.xaml)文件,其中Generic.xaml在项目的Themes文件夹下:
接着就在类中定义我们的属性、依赖属性以及方法、依赖属性变化的回调方法。
经验总结:
1.注册属性和普通属性的区别?什么时候定义普通属性,什么时候定义注册属性并与依赖属性关联?
普通属性:
private int successRate = 100; public int SuccessRate { get { return successRate; } set { if (value != successRate) { successRate = value; OnPropertyChanged("SuccessRate"); } } }
注册属性:(与依赖属性关联)
public static readonly DependencyProperty MeterHeightProperty = DependencyProperty.Register("MeterHeight", typeof(double), typeof(TemperatureGuageControl),new PropertyMetadata((double)100, new PropertyChangedCallback(TemperatureGuageControl.OnAllChanged))); [Description("设置进度条的高度"), Category(TemperatureGuageControl.meterInfo)] public double MeterHeight { get { return (double)GetValue(MeterHeightProperty); } set { SetValue(MeterHeightProperty, value); } }
当这两种类型的属性与空间模板的元素属性绑定时:
普通属性绑定方法:(与MVVM模式一样)
1.在构造函数中:this.DataContext=this
2.绑定时:(在Generic.xaml中)
<ProgressBar Minimum="0" Maximum="100" Value="{Binding SuccessRate, Mode=OneWay}">
注册属性绑定方法:(在Generic.xaml中)
<Canvas x:Name="rootCanvas" Background="Gray" Height="{Binding MeterHeight, RelativeSource={RelativeSource TemplatedParent}}" Width="{Binding MeterWidth, RelativeSource={RelativeSource TemplatedParent}}" Margin="{Binding MeterMargin,RelativeSource={RelativeSource TemplatedParent}}">
而当注册属性值发生变化通知的方法可在注册时的回调方法中处理。
使用场景:
当属性变化要执行一段动画或者要动态加载、生成或布局模板中的子控件时,使用注册属性,其他情况,可以使用普通属性,也可以使用注册属性,一般使用普通属性,这样简便一些。
例如温度计的主刻度个数属性,当主刻度个数变化时,要重新计算并动态生成其他刻度,此时必须使用注册属性。
2.使用注册属性时,默认值第一次加载控件没有应用上,在类中重写OnApplyTemplate方法,使用GetTemplateChild获得的控件为空的解决方法:
出现的原因为控件第一次还没有完全把子控件加载完就调用了OnApplyTemplate方法,所以要在控件加载完之后再调用OnApplyTemplate方法:
static TemperatureGuageControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(TemperatureGuageControl), new FrameworkPropertyMetadata(typeof(TemperatureGuageControl))); } public TemperatureGuageControl() { this.Loaded += TemperatureGuageControl_Loaded; } void TemperatureGuageControl_Loaded(object sender, RoutedEventArgs e) { this.OnApplyTemplate(); CurrentValueChanged(new DependencyPropertyChangedEventArgs(TemperatureGuageControl.CurrentValueProperty, 0, 0)); }
以上两点是个人经验,如果有错误之处,请指正。
本文所有控件打包资源下载
- WPF 定义自己的控件
- 如何定义自己的控件
- 自己定义控件
- 采用C#WPF实现自己的网页浏览器(自定义Tab控件)
- 自己定义一个依赖属性 Wpf
- WPF自制控件如何定义依赖属性
- 二个自己定义控件之间的传值
- Android 如何自己定义控件的样式 Shape
- WPF自定义CheckedListBox控件----写给自己
- WPF 控件的位置
- wpf 自己写的添加Button 控件的方法,留存一份,供参考
- WPF/Blend4之自定义控件——制作自己的Button
- 自己定义的格式
- 定义自己的Adapter
- 定义自己的异常
- 定义自己的快捷键
- 定义自己的View
- 定义自己的xml
- JVM内存模型
- c/c++获取当前时间 自1970年的秒数
- 1073 家族(并查集模板)
- 解决MyEclipse不能正常加载问题
- 【C#】流程控制语句—跳转语句
- WPF 定义自己的控件
- Deep Learning(深度学习)学习笔记整理系列之(四)
- 关于音视频直播技术的总结
- Java调用hdfs出现java.lang.VerifyError: class org.apache.hadoop.hdfs.protocol.proto异常
- POJ 1240 Pre-Post-erous! 笔记
- Android Studio 常见 Build 问题 Error:failed to find Build Tools revision 23.0.2
- 类的构造函数
- 正整数分解质因数(Java详解)
- 云数据中心安全设计要点