Silverlight实用窍门系列:12.继承于某些固定控件(以Grid为例)的鼠标左键双击事件的实现【附带实例源码】

        上一节有位园友提问:“如果我做一个自定义的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的代码如下:

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 下载源代码。

posted @ 2011-02-24 14:00  程兴亮  阅读(2826)  评论(3编辑  收藏