在实际工作中,WPF提供的控件并不能完全满足不同的设计需求。这时,需要我们设计自定义控件。

这里LZ总结一些自己的思路,特性如下:

  • Coupling
  • UITemplate
  • Behaviour
  • Function Package

下面举例说说在项目中我们经常用到调音台音量条,写一个自定义控件模拟调音台音量条。

自定义控件SingnalLight,实现功能

  • 接收来自外部的范围0~100的数值
  • 实时显示接收数值
  • 数值范围0~50显示绿色,50~85显示黄色,85~100显示红色,没有数值显示褐色
  • 可在父控件上拖拽该控件
public class SingnalLight : ContentControl {
public int ValueA {
get { return (int)GetValue(ValueAProperty); }
set { SetValue(ValueAProperty, value); }
} public SingnalLight() {
this.AllowDrop = true;
} static SingnalLight() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(SingnalLight), new FrameworkPropertyMetadata(typeof(SingnalLight)));
} }

ValueA为接受外部数值的属性

2.复写控件UITemplate

 1  <Style TargetType="{x:Type control:SingnalLight}">
2 <Setter Property="RenderTransform">
3 <Setter.Value>
4 <TranslateTransform X="{Binding Path=X,RelativeSource={RelativeSource AncestorType={x:Type control:SingnalLight}}}"
5 Y="{Binding Path=Y,RelativeSource={RelativeSource AncestorType={x:Type control:SingnalLight}}}"/>
6 </Setter.Value>
7 </Setter>
8 <Setter Property="Template">
9 <Setter.Value>
10 <ControlTemplate>
11 <ControlTemplate.Resources>
12 <control:SingnalLightStatusConverter x:Key="colorconverter"></control:SingnalLightStatusConverter>
13 <control:SingnalLightValueConverter x:Key="valueconverter"></control:SingnalLightValueConverter>
14 </ControlTemplate.Resources>
15 <StackPanel>
16 <TextBlock Text="{Binding Path=ValueA,RelativeSource={RelativeSource AncestorType={x:Type control:SingnalLight}}}"></TextBlock>
17 <TextBlock Text="100"></TextBlock>
18 <Border
19 x:Name="bd1"
20 Height="{Binding Path=LightHeight,RelativeSource={RelativeSource AncestorType={x:Type control:SingnalLight}}}"
21 SnapsToDevicePixels="True"
22 BorderBrush="Black" BorderThickness="1" Background="Transparent">
23 <Rectangle Fill="{Binding Path=ValueA,
24 RelativeSource={RelativeSource AncestorType={x:Type control:SingnalLight}},
25 Converter={StaticResource ResourceKey=colorconverter}}"
26 VerticalAlignment="Bottom">
27 <Rectangle.Height>
28 <MultiBinding Converter="{StaticResource ResourceKey=valueconverter}">
29 <Binding Path="ValueA" RelativeSource="{RelativeSource AncestorType={x:Type control:SingnalLight}}"></Binding>
30 <Binding Path="Height" ElementName="bd1"></Binding>
31 </MultiBinding>
32 </Rectangle.Height>
33 </Rectangle>
34 </Border>
35 <TextBlock Text="0"></TextBlock>
36 </StackPanel>
37 </ControlTemplate>
38 </Setter.Value>
39 </Setter>
40 </Style>

3.接受值判断,SingnalLight通过实现IValueConverter和Override Arrange & Measure Methods,实现了UI呈现的绑定,

 1     public class SingnalLightStatusConverter : IValueConverter {
2 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
3 SolidColorBrush result = Brushes.Transparent;
4 if (value.GetType() == typeof(int)) {
5 var color = System.Convert.ToInt32(value);
6 if (color < 50) result = Brushes.Green;
7 else if (color < 85 && color >= 50) result = Brushes.Yellow;
8 else if (color <= 100 && color >= 85) result = Brushes.Red;
9 else result = Brushes.Gray;
10 }
11 return result;
12 }
13
14 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
15 throw new NotImplementedException();
16 }
17 }
18
19 public class SingnalLightValueConverter : IMultiValueConverter {
20 public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
21 double result = 0;
22 if (values[0].GetType() == typeof(int) && values[1].GetType() == typeof(double)) {
23 result = (double)values[1] / 100 * System.Convert.ToDouble(values[0]);
24 }
25 return result;
26 }
27
28 public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
29 throw new NotImplementedException();
30 }
31 }
 
 
1         protected override Size MeasureOverride(Size constraint) {
2 if (ActualHeight > 0) LightHeight = ActualHeight * .7;
3 return base.MeasureOverride(constraint);
4 }
5
6 protected override Size ArrangeOverride(Size arrangeBounds) {
7 return base.ArrangeOverride(arrangeBounds);
8 }
 

4.控件支持拖拽,覆写MouseDown,MouseMove,MouseUp方法。这样写的好处是,如果在父控件的事件中实现Drag,父控件如果有多个对象,这样逻辑会十分混乱。

 
 1         protected override void OnMouseMove(MouseEventArgs e) {
2 base.OnMouseMove(e);
3 if (e.LeftButton == MouseButtonState.Pressed) {
4 _currentPoint = e.GetPosition(this);
5 X += _currentPoint.X - _startPoint.X;
6 Y += _currentPoint.Y - _startPoint.Y;
7 }
8 }
9
10 protected override void OnMouseDown(MouseButtonEventArgs e) {
11 base.OnMouseDown(e);
12 _startPoint = e.GetPosition(this);
13 this.CaptureMouse();
14 }
15
16 protected override void OnMouseUp(MouseButtonEventArgs e) {
17 base.OnMouseUp(e);
18 this.ReleaseMouseCapture();
19 }
 

自定义控件系列博文链接:

WPF自定义控件(一)の控件分类
WPF自定义控件(二)の重写原生控件样式模板
WPF自定义控件(三)の扩展控件
WPF自定义控件(四)の自定义控件
WPF自定义控件(五)の用户控件

WPF自定义控件(四)の自定义控件的更多相关文章

  1. WPF 精修篇 自定义控件

    原文:WPF 精修篇 自定义控件 自定义控件 因为没有办法对界面可视化编辑 所以用来很少 现在实现的是 自定义控件的 自定义属性 和自定义方法 用VS 创建自定义控件后 会自动创建 Themes 文件 ...

  2. wpf 两个自定义控件

    wpf 两个自定义控件 一个是IP控件,一个滑动条.先看下效果图 IPControl 1.实际工作中有时需要设置IP信息,就想着做一个ip控件.效果没有window自带的好,需要通过tab切换.但也能 ...

  3. WPF案例 (四) 模拟Windows7桌面任务栏

    原文:WPF案例 (四) 模拟Windows7桌面任务栏 这个程序模彷了Windows7的桌面任务栏,当在桌面上双击某个快捷方式时,将打开一个新的子界面,并且在任务栏里创建一个链接到此界面的任务栏图标 ...

  4. WPF入门(四)->线形区域Path内容填充之填充图(ImageBrush)

    原文:WPF入门(四)->线形区域Path内容填充之填充图(ImageBrush) 前面我们提到了LinearGradientBrush可以用来画渐变填充图,那么我们同时也可以使用ImageBr ...

  5. WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush)

    原文:WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush) 前面我们介绍到,Path对象表示一个用直线或者曲线连接的图形,我们可以使用Path.Data ...

  6. 好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果

    原文:好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果 版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https:// ...

  7. [WPF自定义控件库] 自定义控件的代码如何与ControlTemplate交互

    1. 前言 WPF有一个灵活的UI框架,用户可以轻松地使用代码控制控件的外观.例设我需要一个控件在鼠标进入的时候背景变成蓝色,我可以用下面这段代码实现: protected override void ...

  8. WPF中关于自定义控件的滚动条鼠标停留在内容上鼠标滚轮滚动无效的问题

    问题起因:在一个用户控件里放置了1个TreeView垂直顺序放置. 当用户控件中的内容超过面板大小时,滚动条会自动出现 ,但是只有当鼠标指示在右边滚动条的那一条位置时,才支持鼠标滚轴滚动. 点在控件内 ...

  9. android自定义控件(四) View中的方法

    onFinishInflate() 当View中所有的子控件 均被映射成xml后触发 onMeasure(int, int) 确定所有子元素的大小 onLayout(boolean, int, int ...

  10. wpf 中的 自定义控件的 binding

    XMl 代码 --------------------------------------------------------------------------------------------- ...

随机推荐

  1. 基于H5的WebSocket简单实例

    客户端代码: <html> <head> <script> var socket; if ("WebSocket" in window) { v ...

  2. 总结下Mysql分表分库的策略及应用

    上月前面试某公司,对于mysql分表的思路,当时简要的说了下hash算法分表,以及discuz分表的思路,但是对于新增数据自增id存放的设计思想回答的不是很好(笔试+面试整个过程算是OK过了,因与个人 ...

  3. 7.QT-Qt对象间的父子关系

    Qt对象之间可以存在父子关系 继承于QObject类或者其子类的对象,都称为Qt对象 当指定Qt对象的父对象时 需要通过setParent()成员函数来设置对象间的父子关系 子对象将会把自己的指针地址 ...

  4. js 位运算符

    MDN定义:位运算符将它的操作数视为32位元的二进制串(0和1组成)而非十进制八进制或十六进制数. 例如:十进制数字9用二进制表示为1001,位运算符就是在这个二进制表示上执行运算,但是返回结果是标准 ...

  5. angularJs - cynthia娆墨旧染-响应式文章发布系统

    (0)功能 a.添加新文章 b.修改已发布文章 c.搜索已经发布的文章 d.demo链接:   http://cynthiawupore.github.io/angularJS (1)界面 a.文章列 ...

  6. Javascript URI 解析介绍

    URI 在维基百科中对于URI的解释是这样子的: 在计算机术语中,统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串. 该种标识 ...

  7. 【代码笔记】Web-JavaScript-JavaScript错误

    一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  8. spring boot 集成 redis lettuce

    一.简介 spring boot框架中已经集成了redis,在1.x.x的版本时默认使用的jedis客户端,现在是2.x.x版本默认使用的lettuce客户端,两种客户端的区别如下 # Jedis和L ...

  9. Mixing a dll boost library with a static runtime is a really bad idea错误的解决

    作者:朱金灿 来源:http://blog.csdn.net/clever101 同事在使用boost库时遇到一个问题,在编译时出现一个错误:Mixing a dll boost library wi ...

  10. Tars 负载均衡

    // 传入主控地址,在 db_tars t_registry_info 表中 Communicator communicator = CommunicatorFactory.getInstance() ...