上一节有位园友提问:“如果我做一个自定义的Grid,跟普通的Grid一样,但是有双击事件,可以实现吗??比如我要用我的Grid,添加引用后直接用,就有双击事件。这样的控件可以做出来吗??”
答案当然是肯定的。在这里我制作了一个实例,因为本类需要完全拥有Grid控件所有的事件,属性和方法,所以它需要继承于Grid控件而不是继承于 UserControl。鼠标右键点击项目名称-->“添加”-->“新建项”-->选择“类”-->修改文件名称为 “NewGrid.cs”,再将public partial class NewGrid :UserControl修改为public partial class NewGrid :Grid让此类完全继承于Grid控件,最后向NewGrid.cs写入以下代码:
- //声明DoubleClick类
- private DoubleClick MouseDoubleClick;
- private MouseLeftDoubleDownEventHandler mouseLeftDoubleDown;
- /// <summary>
- /// 声明右键双击事件的属性
- /// </summary>
- public MouseLeftDoubleDownEventHandler MouseLeftDoubleDown
- {
- get { return mouseLeftDoubleDown; }
- set
- {
- mouseLeftDoubleDown = value;
- //将本控件设置为可双击控件,并且设置需要执行的函数为传递过来的委托
- MouseDoubleClick = new DoubleClick(this);
- this.MouseDoubleClick.mouseLeftDoubleDown += mouseLeftDoubleDown;
- this.Cursor = Cursors.Hand;
- }
- }
此段代码声明了一个MouseLeftDoubleDownEventHandler类型的鼠标右键属 性,MouseLeftDoubleDownEventHandler是声明于DoubleClick类的全局委托变量,在本类中可以引用。当设置 MouseLeftDoubleDown值时,实例化DoubleClick类,并将本控件做为参数初始化DoubleClick类,加载 MouseDoubleClick对象的事件传入NewGrid的mouseLeftDoubleDown属性值(此值里面是需要执行双击事件的方法的委 托)。
下面我们看一下MainPage.xaml.cs类的所有源代码:
- using System.Windows.Controls;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Shapes;
- namespace SLDoubleClick
- {
- public partial class MainPage : UserControl
- {
- public MainPage()
- {
- InitializeComponent();
- //开始后台代码创建一个newGrid类。设置基本属性
- NewGrid newGrid = new NewGrid();
- newGrid.Background = new SolidColorBrush(Colors.Blue);
- newGrid.Width = 100;
- newGrid.Height = 100;
- //设置属性为我们需要执行的函数委托。
- newGrid.MouseLeftDoubleDown = new MouseLeftDoubleDownEventHandler(newGrid_MouseLeftDoubleDowns);
- //添加新的NewGrid的列,然后再添加两个TextBox做实例。
- newGrid.ColumnDefinitions.Insert(0, new ColumnDefinition() { Width = new GridLength(50) });
- newGrid.ColumnDefinitions.Insert(1, new ColumnDefinition() { Width = new GridLength(100) });
- TextBox tb = new TextBox() { Width =50,Height=20,Text="1111"};
- tb.SetValue(Grid.ColumnProperty, 0);
- TextBox tb1 = new TextBox() { Width = 50, Height = 20, Text = "2222" };
- tb1.SetValue(Grid.ColumnProperty,1);
- newGrid.Children.Add(tb);
- newGrid.Children.Add(tb1);
- newGrid.ShowGridLines = true;
- this.LayoutRoot.Children.Add(newGrid);
- }
- void newGrid_MouseLeftDoubleDowns(object sender, MouseButtonEventArgs e)
- {
- MessageBox.Show("您执行了双击事件");
- }
- }
- }
从此段代码可以看出NewGrid类能够实现所有Grid方法,事件和属性,并且添加了一个新的属性,那就是双击事件属性 : newGrid.MouseLeftDoubleDown = new MouseLeftDoubleDownEventHandler(newGrid_MouseLeftDoubleDowns)。据此实例我们就可以为 所有能够触发鼠标单击事件的自定义控件添加鼠标左键双击事件。另外贴出鼠标左键双击类DoubleClick.cs的代码如下:
- using System;
- using System.Threading;
- using System.Windows;
- using System.Windows.Input;
- using System.Windows.Threading;
- namespace SLDoubleClick
- {
- public delegate void MouseLeftDoubleDownEventHandler(object sender, MouseButtonEventArgs e);
- /// <summary>
- /// 定义了双击事件的类
- /// </summary>
- public class DoubleClick
- {
- /// <summary>
- /// 双击事件定时器
- /// </summary>
- private DispatcherTimer doubleClickTimer;
- /// <summary>
- /// 是否单击
- /// </summary>
- private bool isOnceClick;
- /// <summary>
- /// 双击事件
- /// </summary>
- public MouseLeftDoubleDownEventHandler mouseLeftDoubleDown;
- /// <summary>
- /// 拥有双击事件的UI
- /// </summary>
- private UIElement owner;
- /// <summary>
- /// 实例化DoubleClick
- /// </summary>
- /// <param name="owner">具有双击事件的UI</param>
- public DoubleClick(UIElement owner)
- {
- this.owner = owner;
- this.bindEvent();
- }
- /// <summary>
- /// 绑定事件
- /// </summary>
- private void bindEvent()
- {
- //控件被左键单击时绑定一个鼠标点击事件
- this.owner.MouseLeftButtonDown += (new MouseButtonEventHandler(this.owner_MouseLeftButtonDown));
- DispatcherTimer timer = new DispatcherTimer();
- //设置单击事件时间间隔
- timer.Interval = (new TimeSpan(0, 0, 0, 0, 200));
- this.doubleClickTimer = timer;
- //在200毫秒之内部调用此事件,如果超过200毫秒还没有得到第二次点击,则调用此事件
- this.doubleClickTimer.Tick += (new EventHandler(this.doubleClickTimer_Tick));
- }
- /// <summary>
- /// 此事件在超过200毫秒为接受到下一次点击时触发。确定本次是单击事件。
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void doubleClickTimer_Tick(object sender, EventArgs e)
- {
- this.isOnceClick = false;
- this.doubleClickTimer.Stop();
- }
- private void owner_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
- {
- if (!this.isOnceClick)
- { //点击第一次之后开始计时,并且设置此时为单击一次
- this.isOnceClick = true;
- this.doubleClickTimer.Start();
- }
- else
- { //在200毫秒的时间间隔之内并且触发doubleClickTimer_Tick事件。则执行鼠标左键双击事件。
- this.mouseLeftDoubleDown(sender, e);
- }
- }
- }
- }
本实例有Vs2010+Silverlight 4.0编写,点击 SLDoubleClickForGrid.rar 下载源代码。
本文转自程兴亮 51CTO博客,原文链接:http://blog.51cto.com/chengxingliang/821484