如何绑定MouseDoubleClick事件

时间:2010-05-13 10:38:42

标签: c# mvvm binding wpfdatagrid

如何将DataGrid的MouseDoubleClick事件绑定到委托命令并获取该网格的选定项。我想在XAML文件中执行此操作,因为我使用的是Prism 2.0和MVVM模式。

1 个答案:

答案 0 :(得分:2)

请查看附加属性,这将有所帮助。 以下是有用的代码,我已经在某个地方看到了这个,但是不管怎样他都不记得网站或作者的名字了。

/// <summary>
/// The static class the defines the attached command DP for exposing MouseDoubleClick 
/// event as  a command
/// </summary>
public static class CommandMouseDoubleClick
{
    #region TheCommandToRun

    /// <summary>
    /// TheCommandToRun : The actual ICommand to run
    /// </summary>
    public static readonly DependencyProperty TheCommandToRunProperty =
        DependencyProperty.RegisterAttached("TheCommandToRun", typeof(ICommand),
        typeof(CommandMouseDoubleClick),
        new FrameworkPropertyMetadata((ICommand)null));

    /// <summary>  
    /// Gets the TheCommandToRun property.    
    /// </summary>  
    public static ICommand GetTheCommandToRun(DependencyObject d)
    {
        return (ICommand)d.GetValue(TheCommandToRunProperty);
    }

    /// <summary>  
    /// Sets the TheCommandToRun property.
    /// </summary>  
    public static void SetTheCommandToRun(DependencyObject d, ICommand value)
    {
        d.SetValue(TheCommandToRunProperty, value);
    }

    #endregion

    #region RoutedEventName

    /// <summary>  
    /// RoutedEventName : The event that should actually execute the  
    /// ICommand  
    /// </summary>  
    public static readonly DependencyProperty RoutedEventNameProperty =
        DependencyProperty.RegisterAttached("RoutedEventName", typeof(String),
        typeof(CommandMouseDoubleClick),
        new FrameworkPropertyMetadata((String)String.Empty,
            new PropertyChangedCallback(OnRoutedEventNameChanged)));

    /// <summary>  
    /// Gets the RoutedEventName property. 
    /// </summary>
    public static String GetRoutedEventName(DependencyObject d)
    {
        return (String)d.GetValue(RoutedEventNameProperty);
    }

    /// <summary>  
    /// Sets the RoutedEventName property.
    /// </summary>  
    public static void SetRoutedEventName(DependencyObject d, String value)
    {
        d.SetValue(RoutedEventNameProperty, value);
    }

    /// <summary> 
    /// Hooks up a Dynamically created EventHandler (by using the
    /// <see cref="MouseDoubleClickEventHooker">MouseDoubleClickEventHooker</see> class) that when  
    /// run will run the associated ICommand  
    /// </summary>
    private static void OnRoutedEventNameChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        String routedEvent = (String)e.NewValue;
        //If the RoutedEvent string is not null, create a new  
        //dynamically created EventHandler that when run will execute  
        //the actual bound ICommand instance (usually in the ViewModel)  
        if (!String.IsNullOrEmpty(routedEvent))
        {
            MouseDoubleClickEventHooker eventHooker = new MouseDoubleClickEventHooker();
            eventHooker.ObjectWithAttachedCommand = d;
            EventInfo eventInfo = d.GetType().GetEvent(routedEvent,
                BindingFlags.Public | BindingFlags.Instance);
            //Hook up Dynamically created event handler  
            if (eventInfo != null)
            {
                eventInfo.AddEventHandler(d,
                 eventHooker.GetNewEventHandlerToRunCommand(eventInfo));
            }
        }
    }

    #endregion
}

/// <summary> 
/// Contains the event that is hooked into the source RoutedEvent 
/// that was specified to run the ICommand 
/// </summary> 
sealed class MouseDoubleClickEventHooker
{
    #region Properties

    /// <summary> 
    /// The DependencyObject, that holds a binding to the actual 
    /// ICommand to execute 
    /// </summary> 
    public DependencyObject ObjectWithAttachedCommand { get; set; }

    #endregion

    #region Public Methods

    /// <summary> 
    /// Creates a Dynamic EventHandler that will be run the ICommand 
    /// when the user specified RoutedEvent fires 
    /// </summary>
    /// <param name="eventInfo">The specified RoutedEvent EventInfo</param>
    ///<returns>An Delegate that points to a new EventHandler
    /// that will be run the ICommand</returns>
    public Delegate GetNewEventHandlerToRunCommand(EventInfo eventInfo)
    {
        Delegate del = null;
        if (eventInfo == null)
            throw new ArgumentNullException("eventInfo");
        if (eventInfo.EventHandlerType == null)
            throw new ArgumentException("EventHandlerType is null");
        if (del == null)
            del = Delegate.CreateDelegate(eventInfo.EventHandlerType, this,
                GetType().GetMethod("OnEventRaised",
                BindingFlags.NonPublic |
                BindingFlags.Instance));
        return del;
    }

    #endregion

    #region Private Methods
    /// <summary> 
    /// Runs the ICommand when the requested RoutedEvent fires
    /// </summary>
    private void OnEventRaised(object sender, EventArgs e)
    {
        ICommand command = (ICommand)(sender as DependencyObject).
            GetValue(CommandMouseDoubleClick.TheCommandToRunProperty);
        if (command != null)
        {
            command.Execute(null);
        }
    }
    #endregion
}

xaml可能如下所示:

<Label local:CommandMouseLeftButtonDown.RoutedEventName="MouseLeftButtonDown"  
       local:CommandMouseLeftButtonDown.TheCommandToRun="{Binding Path=MouseDownCommand, RelativeSource={RelativeSource TemplatedParent}}"
       local:CommandMouseDoubleClick.RoutedEventName="MouseDoubleClick"  
       local:CommandMouseDoubleClick.TheCommandToRun="{Binding Path=MouseDoubleClickCommand, RelativeSource={RelativeSource TemplatedParent}}"/>