views:

292

answers:

1

How can I bind a MouseDoubleClick event of a DataGrid to a delegate command and get the selected item of that grid.? I want to do this in XAML file as I'm using Prism 2.0 and MVVM pattern.

A: 

Hi, Please look at attached properties, it wil be helpful. The below is the code that will help, i had seen ti somewhere but don't remember the site or author's name thanks to him anyways.

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

//The xaml could look something like below,

&gt 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}}"/>

Zepher
Thanks for your code..
Johnny