2010-01-21 4 views
3

Je veux pouvoir router le double-clic d'une grille vers une commande. J'utilise Rx pour simuler le double-clic mais je n'arrive pas à comprendre à quel contrôle attacher le gestionnaire de la souris (l'événement souris sur l'objet e.Row dans l'événement DataGrid.RowLoading ne semble pas fonctionner).Liaison double d'une ligne à une commande dans une grille de données Silverlight

Quelqu'un a-t-il des idées?

Code Rx pour le traitement du Double-cliquez sur est la suivante:

Observable.FromEvent<MouseButtonEventArgs>(e.Row, "MouseLeftButtonDown").TimeInterval().Subscribe(evt => 
     { 
      if (evt.Interval.Milliseconds <= 300) 
      { 
       // Execute command on double click 
      } 
     }); 

Répondre

4

j'ai changé ce code de manipulation MouseLeftButtonDown à MouseLeftButtonUp et il fonctionne maintenant. La ligne doit avoir quelque chose d'autre qui gère les événements de bouton.

Observable.FromEvent<MouseButtonEventArgs>(e.Row, "MouseLeftButtonUp").TimeInterval().Subscribe(evt => 
    { 
     if (evt.Interval != TimeSpan.Zero && evt.Interval.TotalMilliseconds <= 300) 
     { 
      // Execute command on double click 
     } 
    }); 

Le code source complet est inclus ci-dessous:

CommandBehaviorBase.cs

using System; 
using System.Windows; 
using System.Windows.Input; 
using System.Windows.Interactivity; 

/// <summary> 
/// Provides the base implementation of all Behaviors that can be attached to a <see cref="FrameworkElement"/> which trigger a command. 
/// </summary> 
/// <typeparam name="T">The type of control this behavior can be attached to, must derive from <see cref="FrameworkElement"/>.</typeparam> 
public abstract class CommandBehaviorBase<T> : Behavior<T> where T : FrameworkElement 
{ 
    #region Constants and Fields 

    /// <summary>The DependencyProperty backing store for CommandParameter. This enables animation, styling, binding, etc...</summary> 
    public static readonly DependencyProperty CommandParameterProperty = 
     DependencyProperty.Register(
      "CommandParameter", 
      typeof(object), 
      typeof(CommandBehaviorBase<T>), 
      new PropertyMetadata(null, OnCommandParameterPropertyChanged)); 

    /// <summary>The DependencyProperty backing store for Command. This enables animation, styling, binding, etc...</summary> 
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
     "Command", typeof(ICommand), typeof(CommandBehaviorBase<T>), new PropertyMetadata(null)); 

    #endregion 

    /// <summary> 
    /// Gets or sets the command to execute 
    /// </summary> 
    public ICommand Command 
    { 
     get 
     { 
      return (ICommand)this.GetValue(CommandProperty); 
     } 

     set 
     { 
      this.SetValue(CommandProperty, value); 
     } 
    } 

    /// <summary> 
    /// Gets or sets the command parameter to execute with. 
    /// </summary> 
    public object CommandParameter 
    { 
     get 
     { 
      return this.GetValue(CommandParameterProperty); 
     } 

     set 
     { 
      this.SetValue(CommandParameterProperty, value); 
     } 
    } 

    /// <summary> 
    /// Gets or sets the command binding path (Hack for SL3). 
    /// </summary> 
    /// <remarks>This is a hack to overcome the fact that we cannot 
    /// bind to the Command dependency property due to a limitation in Silverlight 3.0 
    /// This shouldn't be necessary as in Silverlight 4.0 <see cref="DependencyObject"/> supports data binding hooray!</remarks> 
    public string CommandPath { get; set; } 

    /// <summary> 
    /// Gets or sets a value indicating whether this mapping is currently enabled. 
    /// </summary> 
    public bool IsEnabled { get; set; } 

    /// <summary> 
    /// Implements the logic that disables the key mapping based on whether the command can be executed. 
    /// </summary> 
    /// <summary> 
    /// Updates the target object's IsEnabled property based on the commands ability to execute. 
    /// </summary> 
    public virtual void UpdateEnabledState() 
    { 
     if (this.Command == null && !string.IsNullOrEmpty(this.CommandPath)) 
     { 
      this.Command = this.AssociatedObject.DataContext.GetPropertyPathValue<ICommand>(this.CommandPath, null); 
     } 

     if (this.AssociatedObject == null) 
     { 
      this.Command = null; 
      this.CommandParameter = null; 
     } 
     else if (this.Command != null) 
     { 
      this.IsEnabled = this.Command.CanExecute(this.CommandParameter); 
     } 
    } 

    /// <summary> 
    /// Executes the command, if it's set, providing the <see cref="CommandParameter"/> 
    /// </summary> 
    protected virtual void ExecuteCommand() 
    { 
     if (this.Command != null) 
     { 
      this.Command.Execute(this.CommandParameter); 
     } 
    } 

    /// <summary> 
    /// Attaches to the target <see cref="FrameworkElement"/> and sets up the command. 
    /// </summary> 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     this.UpdateEnabledState(); 
    } 

    /// <summary> 
    /// Raised when the command parameter changes, re-evaluates whether the Command can execute 
    /// </summary> 
    /// <param name="sender">The KeyCommandBehavior that command parameter changed for.</param> 
    /// <param name="args">The parameter is not used.</param> 
    private static void OnCommandParameterPropertyChanged(
     DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     ((CommandBehaviorBase<T>)sender).UpdateEnabledState(); 
    } 
} 

DoubleClickCommandBehavior.cs

using System; 
using System.Linq; 
using System.Windows; 
using System.Windows.Input; 

/// <summary> 
/// Provides behavior for any clickable control and will execute a command when the control is double clicked. 
/// Does not disable the control if the command cannot be executed. 
/// </summary> 
public class DoubleClickCommandBehavior : CommandBehaviorBase<FrameworkElement> 
{ 
    #region Constants and Fields 

    /// <summary> 
    /// Stores the observable that subscribes to click events. 
    /// </summary> 
    private IDisposable observable; 

    #endregion 

    #region Constructors and Destructors 

    /// <summary> 
    /// Initializes a new instance of the DoubleClickCommandBehavior class. 
    /// </summary> 
    public DoubleClickCommandBehavior() 
    { 
     // Default double-click interval is 220 milliseconds. 
     this.Interval = 220; 
    } 

    #endregion 

    /// <summary> 
    /// Gets or sets the double click interval in milliseconds. 
    /// </summary> 
    public int Interval 
    { 
     get; 
     set; 
    } 

    /// <summary> 
    /// Subscribes to the MouseLeftButtonUp of the data grid and times the intervals between the events, 
    /// if the time between clicks is less than the configured interval the command is executed. 
    /// </summary> 
    /// <remarks>Originally attached to MouseLeftButtonDown but the events were not firing.</remarks> 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     this.observable = 
      Observable.FromEvent<MouseButtonEventArgs>(this.AssociatedObject, "MouseLeftButtonUp").TimeInterval(). 
       Subscribe(
        evt => 
        { 
         if (evt.Interval != TimeSpan.Zero && evt.Interval.TotalMilliseconds <= this.Interval) 
         { 
          this.UpdateEnabledState(); 
          this.ExecuteCommand(); 
         } 
        }); 
    } 

    /// <summary> 
    /// Disposes of the observable 
    /// </summary> 
    protected override void OnDetaching() 
    { 
     if (this.observable != null) 
     { 
      this.observable.Dispose(); 
      this.observable = null; 
     } 

     base.OnDetaching(); 
    } 
} 
+0

Salut, une chance de partager tout votre exemple de commande pour cela? – Jordan

0

Je vais avoir des problèmes similaires (bien que vous n'utilisiez pas Rx pour gérer le double clic, mais plutôt un DoubleClickTrigger générique). Mon problème spécifique est plus lié au fait que je ne suis pas sûr de savoir comment et où connecter mon déclencheur. J'ai essayé quelque chose comme ce qui suit:

    <data:DataGrid.Resources> 
         <ControlTemplate x:Key="rowTemplate" TargetType="data:DataGridRow"> 
          <data:DataGridRow> 
           <fxui:Interaction.Triggers> 
            <fxui:DoubleClickTrigger> 
             <Interactivity:InvokeCommandAction Command="{Binding Source={StaticResource selectCommand}}" CommandParameter="{Binding}"/> 
            </fxui:DoubleClickTrigger> 
           </fxui:Interaction.Triggers> 
          </data:DataGridRow> 
         </ControlTemplate> 
        </data:DataGrid.Resources> 
        <data:DataGrid.RowStyle> 
         <Style TargetType="data:DataGridRow"> 
          <Setter Property="Template" Value="{StaticResource rowTemplate}"/> 
         </Style> 

        </data:DataGrid.RowStyle> 

Avec pas de chance.

Questions connexes