在实际工作中,面对不同的客户需求,需要让空间显示出不同的效果。当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 自定义控件的更多相关文章

  1. WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...

  2. WPF自定义控件与样式(1)-矢量字体图标(iconfont)

    一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...

  3. WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...

  4. WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享

    系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...

  5. WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...

  6. WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...

  7. WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Scr ...

  8. WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...

  9. WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 下拉选 ...

  10. WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 菜单M ...

随机推荐

  1. android 检测网络是否连接,或者GPS是否可用

    很多android程序在打开时,检测网络是否连接,或者GPS是否可用: 1.网络是否连接(包括Wifi和移动网络) // 是否有可用网络 private boolean isNetworkConnec ...

  2. 传智播客JavaWeb day06-jstl

    一.jsp标签(sun公司提供的) 二.EL表达式 三.jstl (javaserver pages standard tag library) 1.为什么要有jstl jsp标签太弱,el表达式功能 ...

  3. Xcode与OX 版本对照表

    xcode1.0-xcode2.x 版本 OS X运行版本 OS X SDK(s) 1.0 OS X Panther(10.3.x) OS X Puma(10.1.x),OS X Jaguar(10. ...

  4. C++模板中的函数对象

    在C++模板类map中一个参数为Compare类型,该类型为一个比较函数,其完整定义如下: template< class Key, class T, class Compare = std:: ...

  5. Nagios NSclient Failed to get CPU value: \238(_total)\6: Failed to get mutex :(

    一台Windows Server 2012的nsclient出现以下的错误,表示无法获得CPU信息 2016-08-08 10:31:33: e:..\..\..\..\trunk\modules\C ...

  6. 2016年中国大学生程序设计竞赛(合肥)-重现赛1009 HDU 5969

    最大的位或 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  7. 体验一下cygwin

    一直在windows下使用gvim,为了更方便的使用cscope.先是写了bat脚本,发现太不方便了. 于是想到了cygwin.下载安装工具就可以了进行默认安装了,配置比较简单. 调整包: ./set ...

  8. C#常见控件命名规则举例

    控件       缩写  举例 Adrotator adrt adrtTopAd BulletedList blst blstCity Button btn btnSubmit Calendar ca ...

  9. asp.net ajax 调用一例

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  10. Android画图Path的使用

    /**       * Paint类介绍       *        * Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色,       * 样式等绘制信息,指定了如何绘制文本 ...