2012-03-19 15 views
8

creé el comportamiento de cuadrícula de datos para detectar haga doble clic en:Silverlight 5 Haga doble clic siempre devuelve ClickCount como 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); 
     } 
    } 

Todo parece estar bien, excepto que no se registra varios clics. En OnMouseLeftButtonUp ClickCount siempre 1. ¿Alguien sabe por qué?

+0

Como un par de verificaciones de cordura, quizás ejecute la muestra de Pete para validar que funciona y/o ejecute uno de los proyectos SL4 DataGrid + DoubleClick existentes como http://www.codeproject.com/Articles/115405/Double-Click -DataGrid-en-Silverlight? –

+0

Lo que estoy haciendo es parte de la actualización de SL5. Deshacerse de este tipo de código ya que multi-clic en realidad "compatible" ... Tengo código de trabajo. Solo quiero hacerlo bien. – katit

Respuesta

3

Bueno, el problema más grande aquí es que cuando se hace clic en las filas de una cuadrícula de datos , MouseLeftButtonDown no se genera, porque este clic se maneja en el nivel de fila.

He dejado de lidiar con algunos controles directamente. Tengo mi propia versión derivada de DataGrid, DataForm y etc. Esto solo hace que mi solución sea fácil de implementar, porque de todos modos no utilizo las versiones de vanilla.

Agregué un nuevo evento llamado ClickIncludingHandled, es un poco prolijo pero describe correctamente lo que está sucediendo y aparecerá muy bien justo debajo Haga clic con IntelliSense - si el control tiene un evento Click para comenzar.

De todos modos, a continuación se detalla mi implementación. A continuación, puede suscribirse a este evento y utilizar ClickCount para determinar la cantidad de clics que desea capturar. Noté que es un poco lento, pero funciona limpiamente.

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

Me encontré con este mismo problema. No pude resolverlo de ninguna manera sensata, así que me puse a trabajar de la siguiente manera:

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); 
    } 

Está sucio pero funciona.

+0

Técnicamente, debe usar SystemInformation.DoubleClickTime y comprobar que cada clic esté dentro de SystemInformation.DoubleClickSize – EricLaw

+0

La clase SystemInformation se encuentra en System.Windows.Forms y, por lo tanto, no está disponible en Silverlight. –

1

MouseButtonUp está roto con respecto a la captura de ClickCount en WPF y Silverlight (se ha grabado muchas veces, pero Microsoft ha optado por no repararlo). Necesita usar eventos MouseButtonDown.

11

Encontré una solución muy simple. Basta con sustituir la sintaxis de registro controlador de eventos

myDataGrid.MouseLeftButtonDown += this.MyDataGrid_MouseLeftButtonDown; 

con la sintaxis AddHandler

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

De esa manera la magia handledEventsToo argumento booleano puede ser especificado.

Esto, bueno, manejará los eventos manejados también.

+0

Esto funciona muy bien :-) Luego usa cosas de interactividad para llevar el evento hasta la VM y eres oro –

+0

Me trabajó y me dio +1. No es necesario tener el 'handledEventsToo:' allí, pero supongo que no duele nada. – McAden

+1

es una buena práctica para las llamadas a métodos cuando los argumentos se especifican con literales como * true * o * 42 * en lugar de variables descriptivas. Hace que el código sea más legible. – herzmeister

Cuestiones relacionadas