上一节有位园友提问:“如果我做一个自定义的Grid,跟普通的Grid一样,但是有双击事件,可以实现吗??比如我要用我的Grid,添加引用后直接用,就有双击事件。这样的控件可以做出来吗??”

        答案当然是肯定的。在这里我制作了一个实例,因为本类需要完全拥有Grid控件所有的事件,属性和方法,所以它需要继承于Grid控件而不是继承于 UserControl。鼠标右键点击项目名称-->“添加”-->“新建项”-->选择“类”-->修改文件名称为 “NewGrid.cs”,再将public partial class NewGrid :UserControl修改为public partial class NewGrid :Grid让此类完全继承于Grid控件,最后向NewGrid.cs写入以下代码:

 

  1. //声明DoubleClick类 
  2.     private DoubleClick MouseDoubleClick; 
  3.      
  4.     private MouseLeftDoubleDownEventHandler mouseLeftDoubleDown; 
  5.     /// <summary> 
  6.     /// 声明右键双击事件的属性 
  7.     /// </summary> 
  8.     public MouseLeftDoubleDownEventHandler MouseLeftDoubleDown 
  9.     { 
  10.         get { return mouseLeftDoubleDown; } 
  11.         set 
  12.         { 
  13.             mouseLeftDoubleDown = value; 
  14.             //将本控件设置为可双击控件,并且设置需要执行的函数为传递过来的委托 
  15.             MouseDoubleClick = new DoubleClick(this); 
  16.             this.MouseDoubleClick.mouseLeftDoubleDown += mouseLeftDoubleDown; 
  17.             this.Cursor = Cursors.Hand; 
  18.         } 
  19.     } 

        此段代码声明了一个MouseLeftDoubleDownEventHandler类型的鼠标右键属 性,MouseLeftDoubleDownEventHandler是声明于DoubleClick类的全局委托变量,在本类中可以引用。当设置 MouseLeftDoubleDown值时,实例化DoubleClick类,并将本控件做为参数初始化DoubleClick类,加载 MouseDoubleClick对象的事件传入NewGrid的mouseLeftDoubleDown属性值(此值里面是需要执行双击事件的方法的委 托)。

        下面我们看一下MainPage.xaml.cs类的所有源代码:

 

  1. using System.Windows.Controls; 
  2. using System.Windows.Documents; 
  3. using System.Windows.Input; 
  4. using System.Windows.Media; 
  5. using System.Windows.Media.Animation; 
  6. using System.Windows.Shapes; 
  7.  
  8. namespace SLDoubleClick 
  9. public partial class MainPage : UserControl 
  10. public MainPage() 
  11. InitializeComponent(); 
  12. //开始后台代码创建一个newGrid类。设置基本属性 
  13. NewGrid newGrid = new NewGrid(); 
  14. newGrid.Background = new SolidColorBrush(Colors.Blue); 
  15. newGrid.Width = 100; 
  16. newGrid.Height = 100; 
  17. //设置属性为我们需要执行的函数委托。 
  18. newGrid.MouseLeftDoubleDown = new MouseLeftDoubleDownEventHandler(newGrid_MouseLeftDoubleDowns); 
  19.  
  20. //添加新的NewGrid的列,然后再添加两个TextBox做实例。 
  21. newGrid.ColumnDefinitions.Insert(0, new ColumnDefinition() { Width = new GridLength(50) }); 
  22. newGrid.ColumnDefinitions.Insert(1, new ColumnDefinition() { Width = new GridLength(100) }); 
  23. TextBox tb = new TextBox() { Width =50,Height=20,Text="1111"}; 
  24. tb.SetValue(Grid.ColumnProperty, 0); 
  25. TextBox tb1 = new TextBox() { Width = 50, Height = 20, Text = "2222" }; 
  26. tb1.SetValue(Grid.ColumnProperty,1); 
  27. newGrid.Children.Add(tb); 
  28. newGrid.Children.Add(tb1); 
  29. newGrid.ShowGridLines = true
  30.  
  31.  
  32. this.LayoutRoot.Children.Add(newGrid); 
  33.  
  34. void newGrid_MouseLeftDoubleDowns(object sender, MouseButtonEventArgs e) 
  35. MessageBox.Show("您执行了双击事件"); 

        从此段代码可以看出NewGrid类能够实现所有Grid方法,事件和属性,并且添加了一个新的属性,那就是双击事件属性 : newGrid.MouseLeftDoubleDown = new MouseLeftDoubleDownEventHandler(newGrid_MouseLeftDoubleDowns)。据此实例我们就可以为 所有能够触发鼠标单击事件的自定义控件添加鼠标左键双击事件。另外贴出鼠标左键双击类DoubleClick.cs的代码如下:

DoubleClick.cs
  1. using System; 
  2. using System.Threading; 
  3. using System.Windows; 
  4. using System.Windows.Input; 
  5. using System.Windows.Threading; 
  6.  
  7. namespace SLDoubleClick 
  8. public delegate void MouseLeftDoubleDownEventHandler(object sender, MouseButtonEventArgs e); 
  9.  
  10. /// <summary> 
  11. /// 定义了双击事件的类 
  12. /// </summary> 
  13. public class DoubleClick 
  14. /// <summary> 
  15. /// 双击事件定时器 
  16. /// </summary> 
  17. private DispatcherTimer doubleClickTimer; 
  18.  
  19. /// <summary> 
  20. /// 是否单击 
  21. /// </summary> 
  22. private bool isOnceClick; 
  23.  
  24. /// <summary> 
  25. /// 双击事件 
  26. /// </summary> 
  27. public MouseLeftDoubleDownEventHandler mouseLeftDoubleDown; 
  28.  
  29. /// <summary> 
  30. /// 拥有双击事件的UI 
  31. /// </summary> 
  32. private UIElement owner; 
  33.  
  34. /// <summary> 
  35. /// 实例化DoubleClick 
  36. /// </summary> 
  37. /// <param name="owner">具有双击事件的UI</param> 
  38. public DoubleClick(UIElement owner) 
  39. this.owner = owner; 
  40. this.bindEvent(); 
  41.  
  42. /// <summary> 
  43. /// 绑定事件 
  44. /// </summary> 
  45. private void bindEvent() 
  46. //控件被左键单击时绑定一个鼠标点击事件 
  47. this.owner.MouseLeftButtonDown += (new MouseButtonEventHandler(this.owner_MouseLeftButtonDown)); 
  48. DispatcherTimer timer = new DispatcherTimer(); 
  49. //设置单击事件时间间隔 
  50. timer.Interval = (new TimeSpan(0, 0, 0, 0, 200)); 
  51. this.doubleClickTimer = timer; 
  52. //在200毫秒之内部调用此事件,如果超过200毫秒还没有得到第二次点击,则调用此事件 
  53. this.doubleClickTimer.Tick += (new EventHandler(this.doubleClickTimer_Tick)); 
  54. /// <summary> 
  55. /// 此事件在超过200毫秒为接受到下一次点击时触发。确定本次是单击事件。 
  56. /// </summary> 
  57. /// <param name="sender"></param> 
  58. /// <param name="e"></param> 
  59. private void doubleClickTimer_Tick(object sender, EventArgs e) 
  60. this.isOnceClick = false
  61. this.doubleClickTimer.Stop(); 
  62.  
  63. private void owner_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
  64. if (!this.isOnceClick) 
  65. { //点击第一次之后开始计时,并且设置此时为单击一次 
  66. this.isOnceClick = true
  67. this.doubleClickTimer.Start(); 
  68. else 
  69. { //在200毫秒的时间间隔之内并且触发doubleClickTimer_Tick事件。则执行鼠标左键双击事件。 
  70. this.mouseLeftDoubleDown(sender, e); 

        本实例有Vs2010+Silverlight 4.0编写,点击 SLDoubleClickForGrid.rar 下载源代码。