WPF 自定义控件
在实际工作中,面对不同的客户需求,需要让空间显示出不同的效果。当style已经不能足够满足客户需求时,就需要程序猿自己设计自定义控件了。
根据工作经历,LZ做了个关于自定义控件的小Demo,仅供参考。
实现操作分为三部分,话不多说,直接上代码。
一.控件后台设置
public class ImageButton : Button
{
public ImageButton() {
this.PreviewMouseDown += ImageButton_PreviewMouseDown;
this.PreviewMouseUp += ImageButton_PreviewMouseUp;
} void ImageButton_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("");
} void ImageButton_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show(""); } public ImageSource ImageSource
{
get { return (ImageSource)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
} public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata(null));
}
根据控件需求对这个类做不同的继承,LZ做的控件是Button,所以继承自Button。
然后对ImageSource对应下文的Binding,做依赖属性。
this.PreviewMouseDown+=PreviewMouseDown;是对Button本身的响应事件做绑定。
二.控件界面设定
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:helper="clr-namespace:DemoZDY">
<Style TargetType="{x:Type helper:ImageButton}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Cursor" Value="Hand" />
<Setter Property="FontFamily" Value="微软雅黑" />
<Setter Property="FontSize" Value=""/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type helper:ImageButton}">
<StackPanel>
<Image Name="Image" Stretch="Fill" Source="{TemplateBinding ImageSource}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
控件内容比较简单,上面一个图片,下面一个Text内容。
Helper是指(一)中的命名空间。
三.MainWindow界面
<Window x:Class="DemoZDY.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width=""
xmlns:helper="clr-namespace:DemoZDY">
<StackPanel>
<helper:ImageButton ImageSource="Status-False.png" Width="" Content="Click"/>
</StackPanel>
</Window>
简单一个自定义控件完成。但该控件不是很具体,下面再写一个稍微复杂点的自定义Buton控件。
四.新自定义button
控件界面差别不大,主要是后台代码和使用的图片资源不同。
(1)图片

点击效果:正常状态下显示上半部分,在被点击时显示下半部分,点击后恢复上半部分。
(2)控件后台代码
[TemplatePart(Name = "PART_Image", Type = typeof(Image))]
public class HoverButton : Button
{
private void OnImageSourceChanged(ImageSource oldValue, ImageSource newValue)
{
if (newValue is BitmapSource)
{
int w = (int)(newValue.Width);
int h = (int)(newValue.Height / ); NormalImage = new CroppedBitmap(newValue as BitmapSource, new Int32Rect(, , w, h));
PressedImage = new CroppedBitmap(newValue as BitmapSource, new Int32Rect(, h, w, h));
}
} public HoverButton()
{
this.PreviewMouseDown += OnPreviewMouseDown;
this.PreviewMouseUp += OnPreviewMouseUp;
} private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (image != null)
{
image.Source = PressedImage;
this.CaptureMouse();
}
//e.Handled = true;
} private void OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (image != null)
{
if (this.IsMouseCaptured)
{
this.ReleaseMouseCapture();
} image.Source = NormalImage;
this.OnClick();
}
//e.Handled = true;
} public override void OnApplyTemplate()
{
base.OnApplyTemplate();
image = this.GetTemplateChild("PART_Image") as Image;
} public ImageSource ImageSource
{
get { return (ImageSource)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
} public ImageSource NormalImage
{
get { return (ImageSource)GetValue(NormalImageProperty); }
set { SetValue(NormalImageProperty, value); }
} public ImageSource PressedImage
{
get { return (ImageSource)GetValue(PressedImageProperty); }
set { SetValue(PressedImageProperty, value); }
} public static void OnImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as HoverButton).OnImageSourceChanged(e.OldValue as ImageSource, e.NewValue as ImageSource);
} static HoverButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(HoverButton), new FrameworkPropertyMetadata(typeof(HoverButton)));
} public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(HoverButton), new UIPropertyMetadata(null, OnImageSourceChanged)); public static readonly DependencyProperty NormalImageProperty =
DependencyProperty.Register("NormalImage", typeof(ImageSource), typeof(HoverButton), new UIPropertyMetadata(null)); public static readonly DependencyProperty PressedImageProperty =
DependencyProperty.Register("PressedImage", typeof(ImageSource), typeof(HoverButton), new UIPropertyMetadata(null)); public Image image;
}
- [TemplatePart(Name = "PART_Image", Type = typeof(Image))],是一种契约,意思是告诉要来写ControlTemplate的用户 , 你的ControlTemplate中需要有一个x:Name为“PART_Image” , 类型为Image, 当然这个类型可以是继承来的, 为什么一定要包含这些契约规定的元素 , 因为逻辑部分对这些东西进行了引用,它们将对控件的默认行为起着关键作用, 可以理解为这个控件的最基本元素 , 是实现默认行为的最小集合, 自然,你的ControlTemplate中如果没有包含契约中的内容 , 则相应的逻辑将无法实现。
- OnImageSourceChanged里意思是将图片分为上下两部分(NormalImage和PressedImage)
- CaptureMouse和ReleaseMouseCapture是指光标的捕获和释放。
- OnApplyTemplate 显示由自定义控件定义的 OnApplyTemplate 重写,设计该自定义控件是因为考虑到调用方可能通过模板和样式系统来定义和应用自己的控件模板。 作为其定义的一部分,模板中命名元素的控件属性是必需的,如 UpButtonElement。 然后 OnApplyTemplate 在加载模板时基于此命名协定检索对象引用。 此外,此示例还调用专用方法 UpdateState(未显示定义)。 这是 OnApplyTemplate 的另一个常见方案:确保为控件的起始状态设置可视状态,在此例中,通过调用专用方法来确保,该专用方法考虑了控件的所有已定义状态并调用 GoToState 来设置适当的状态。 (msdn.microsoft.com中的定义)
- 其他的都很简单,切记要依赖属性。
五.Demo下载
WPF 自定义控件的更多相关文章
- WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...
- WPF自定义控件与样式(1)-矢量字体图标(iconfont)
一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...
- WPF自定义控件与样式(2)-自定义按钮FButton
一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...
- WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享
系列文章目录 WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...
- WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...
- WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...
- WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Scr ...
- WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...
- WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 下拉选 ...
- WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 菜单M ...
随机推荐
- 遇到tomcat端口被占用问题解决方案
1) 启动Eclipse的Tomcat5.0时,报以下错误: 2)根据以上提示显示:Tomcat Server 的8080端口已经被占用.查看它被哪个占用,方法如下: 3)可以看到占用此端口的PID为 ...
- js 开启video全屏模式
方法一: function launchFullScreen() { var element = document.documentElement; if(element.requestFullScr ...
- oracle数据本机自动备份
1.创建三个文件 exp.list 内容:oracle数据库的用户名和密码 name pwd exp.log 主要用于存储在自动备份数据库时的日志信息 exp.sh #!/bin/sh #找到数 ...
- 在linux和windows下自动备份数据库
摘要: 详细介绍在windows和linux下自动备份数据库的过程,希望可以让新手立即上手吧! 本文档内容共分为2大部分:linux和windows Linux和windows都分为:准备工作和操作阶 ...
- POJ-3261 Milk Patterns(后缀数组)
题目大意:找出至少出现K次的子串的最长长度. 题目分析:二分枚举长度x,判断有没有最长公共前缀不小于x的并且连续出现了至少k次的有序子串区间. 代码如下: # include<iostream& ...
- 关于tomcat7下websocket不能使用
tomcat启动时提示 信息: JSR 356 WebSocket (Java WebSocket 1.0) support is not available when running on Java ...
- sip_hangup_disposition
sip_hangup_disposition This variable contains the value of who sent the SIP BYE message. Some exampl ...
- NUnit笔记
注意:单元测试中,Case 与 Case 之间不能有任何关系 测试方法不能有返回值,不能有参数,测试方法必须声明为 public [TestFixture] //声明测试类 [SetUp] //建立, ...
- python学习-day12:列表、元祖、字典介绍和内置
list:列表 >>>----可以被修改.修改成元素,元素可以使单独的数字,也可以是:新的list. 通过:链表..每个元素存储的时候,同时会指向下一个元素. 二.list编辑修改方 ...
- 解读(function($){...})(jQuery)
function(arg){...}这就定义了一个匿名函数,参数为arg 而调用函数 时,是在函数后面写上括号和实参的,由于操作符的优先级,函数本身也需要用括号,即:(function(arg){.. ...