的Silverlight 5双击总是返回作为的ClickCount 1

问题描述:

我创造行为的DataGrid检测双击:的Silverlight 5双击总是返回作为的ClickCount 1

public class DataGridDoubleClickBehavior : Behavior<DataGrid>  
    { 
     public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
      "CommandParameter", 
      typeof(object), 
      typeof(DataGridDoubleClickBehavior), 
      new PropertyMetadata(null));   

     public object CommandParameter 
     { 
      get { return GetValue(CommandParameterProperty); }    
      set { SetValue(CommandParameterProperty, value); } 
     } 

     public static readonly DependencyProperty DoubleClickCommandProperty = DependencyProperty.Register(
      "DoubleClickCommand", 
      typeof(ICommand), 
      typeof(DataGridDoubleClickBehavior), 
      new PropertyMetadata(null));  

     public ICommand DoubleClickCommand 
     { 
      get { return (ICommand)GetValue(DoubleClickCommandProperty); }    
      set { SetValue(DoubleClickCommandProperty, value); } 
     } 

     protected override void OnAttached() 
     { 
      this.AssociatedObject.LoadingRow += this.OnLoadingRow; 
      this.AssociatedObject.UnloadingRow += this.OnUnloadingRow; 

      base.OnAttached(); 
     } 

     protected override void OnDetaching() 
     { 
      this.AssociatedObject.LoadingRow -= this.OnLoadingRow; 
      this.AssociatedObject.UnloadingRow -= this.OnUnloadingRow; 

      base.OnDetaching(); 
     } 

     private void OnLoadingRow(object sender, DataGridRowEventArgs e) 
     { 
      e.Row.MouseLeftButtonUp += this.OnMouseLeftButtonUp; 
     } 

     private void OnUnloadingRow(object sender, DataGridRowEventArgs e) 
     { 
      e.Row.MouseLeftButtonUp -= this.OnMouseLeftButtonUp; 
     } 

     private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
     { 
      if (e.ClickCount < 2) return; 

      if (this.DoubleClickCommand != null) this.DoubleClickCommand.Execute(this.CommandParameter); 
     } 
    } 

一切似乎只是它不注册多次点击的罚款。在OnMouseLeftButtonUp ClickCount总是1.有人知道为什么吗?

+0

作为一对健康检查,可能运行皮特的示例来验证它的工作原理和/或运行一个现有的SL4 DataGrid + DoubleClick项目,如http://www.codeproject.com/Articles/115405/Double-Click -DataGrid-in-Silverlight? – 2012-03-19 10:31:27

+0

我正在做的是SL5升级的一部分。摆脱这样的代码,因为实际上“支持”多点击......我有工作代码。我只是想说得对。 – katit 2012-03-19 15:36:21

不是100%肯定这是问题,但我注意到,皮特·布朗的示例使用的MouseLeftButtonDown代替:

http://10rem.net/blog/2011/04/13/silverlight-5-supporting-double-and-even-triple-click-for-the-mouse

+0

我试过MouseDown,但它是一样的。 – katit 2012-03-19 04:49:02

嗯,这里更大的问题是,当你点击一个DataGrid的行,MouseLeftButtonDown不会引发,因为此点击正在行级别处理。

我很久以前就放弃了直接处理一些控件。我有我自己的DataGrid,DataForm等衍生版本。这只会让我的解决方案容易推出,因为我不使用香草版本。

我添加了一个名为ClickIncludingHandled的新事件,它有点罗嗦,但它恰当地描述了正在发生的事情,并很好地显示在下面点击IntelliSense - 如果控件有一个Click事件开始。

无论如何,下面是我的实施。然后,您可以订阅此事件并使用ClickCount来确定要捕获的点击次数。我注意到它有点慢,但它工作干净。

public partial class DataGridBase : DataGrid 
{ 
     public event MouseButtonEventHandler ClickIncludingHandled; 

     public DataGridBase() : base() 
     { 
      this.AddHandler(MouseLeftButtonDownEvent, new MouseButtonEventHandler(OnClickInclHandled), true); 
     } 

     private void OnClickInclHandled(object sender, MouseButtonEventArgs e) 
     { 
      if (ClickIncludingHandled != null) 
      { 
       ClickIncludingHandled(sender, e); 
      } 
     } 
} 

我遇到了这个完全相同的问题。我无法以任何明智的方式解决它,所以解决它像这样:

private DateTime _lastClickTime; 
    private WeakReference _lastSender; 

    private void Row_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     var now = DateTime.Now; 
     if ((now - _lastClickTime).TotalMilliseconds < 200 && _lastSender != null && _lastSender.IsAlive && _lastSender.Target == sender) 
     { 
      if (Command != null) 
      { 
       Command.Execute(CommandParameter); 
      } 
     } 
     _lastClickTime = now; 
     _lastSender = new WeakReference(sender); 
    } 

它很脏,但它的工作原理。

+0

从技术上讲,应使用SystemInformation.DoubleClickTime,并检查每次单击是否在SystemInformation.DoubleClickSize中。 – EricLaw 2012-09-02 17:57:31

+0

SystemInformation类位于System.Windows.Forms中,因此在Silverlight中不可用。 – 2012-09-03 23:24:04

MouseButtonUp在WPF和Silverlight中捕获ClickCount(已记录多次,但微软已选择不修复它)方面存在问题。您需要使用MouseButtonDown事件。

我发现了一个非常简单的解决方案。刚刚与AddHandler语法

myDataGrid.AddHandler(DataGrid.MouseLeftButtonDownEvent, 
    new MouseButtonEventHandler(this.MyDataGrid_MouseLeftButtonDown), 
    handledEventsToo: true) 

这样可以指定魔布尔handledEventsToo说法取代了事件处理登记语法

myDataGrid.MouseLeftButtonDown += this.MyDataGrid_MouseLeftButtonDown; 

这也可以处理处理事件了。

+0

这很好地工作:-)然后使用交互性的东西,让事件到虚拟机,你是黄金 – 2012-05-18 05:49:23

+0

为我工作,给了+1。你不必在那里拥有'handledEventsToo:',但我想这不会伤害任何东西。 – McAden 2012-09-05 19:50:07

+1

当使用* true *或* 42 *等文字指定参数而不是描述性变量时,对于方法调用来说这是一个很好的做法。使代码更具可读性。 – herzmeister 2012-09-06 10:16:31