2012-03-19 46 views
8

我創造行爲的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

回答

3

嗯,這裏更大的問題是,當你點擊一個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); 
      } 
     } 
} 
0

我遇到了這個完全相同的問題。我無法以任何明智的方式解決它,所以解決它像這樣:

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

1

MouseButtonUp在WPF和Silverlight中捕獲ClickCount(已記錄多次,但微軟已選擇不修復它)方面存在問題。您需要使用MouseButtonDown事件。

11

我發現了一個非常簡單的解決方案。剛剛與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