Binding a double-click row to a command in a Silverlight data grid

I want to be able to route a double-click grid on a command. I use Rx to simulate a double click, but I cannot figure out which control to connect the mouse handler (the mouse event on the e.Row object in the DataGrid.RowLoading event does not work).

Does anyone have any ideas?

The Rx code for double-click processing is as follows:

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

I changed this code from processing MouseLeftButtonDown to MouseLeftButtonUp, and now it works. The line should have something else handling button events.

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

The full source code is given below:

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 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 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();
    }
}
+4

( Rx , DoubleClickTrigger). , , . - :

                    <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>

.

0

Source: https://habr.com/ru/post/1729329/


All Articles