3

I have a DataGrid style template that I wish to add double click behaviour to. The binding should be correct but I cannot seem to get the xaml compiling / working.

All objects added to an IDictionary must have a Key attribute or some other type of key associated with them.

What is wrong with the code below?

<Style TargetType="{x:Type DataGridRow}">
    <EventSetter Event="MouseDoubleClick" Handler="{Binding Connect}"/>

Update per Viktor's comment (gives exact same error):

<Style x:Key="dataGridRowStyle" TargetType="{x:Type DataGridRow}">
    <EventSetter Event="PreviewMouseDoubleClick" Handler="{Binding Connect}"/>
Chris
  • 26,744
  • 48
  • 193
  • 345
  • Thats for a ListView, and my code is nigh on identical but I still get that error... – Chris May 14 '13 at 10:40
  • ok... this problem is probably elsewhere. provide x:Key for that Style. It will be ok. – Kapitán Mlíko May 14 '13 at 10:47
  • THanks but that gives me the exact same error... – Chris May 14 '13 at 10:51
  • wow. It was **my bad**... now I just figured out, that TargetType should be enough for this type of error. Sorry. But those two lines of code really look ok. and I found many questions with these exact same two lines of code. For examlple [here](http://stackoverflow.com/q/3120616/1456174) it's same except of the binding. but if you binding to command in eventsetter it should be done differently I think. [here](http://stackoverflow.com/q/7755003/1456174) – Kapitán Mlíko May 14 '13 at 11:06
  • I saw those before and seemed to require custom code.. I opted for a different approach of having a local double click handler which then raises the command on the DataGridRow.Item which is passed back, not perfect but close enough.. Thanks – Chris May 14 '13 at 11:08

3 Answers3

6

One can use DataGrid InputBindings to achieve goal:

<DataGrid.InputBindings>
   <MouseBinding MouseAction="LeftDoubleClick" Command="{Binding SomeCommand}" />
</DataGrid.InputBindings>
Igor
  • 1,835
  • 17
  • 15
3

You can apply the following behavior on data grid row and follow the usage for implementation.

Double Click Behavior

    public class DoubleClickBehavior
    {
        #region DoubleClick

        public static DependencyProperty OnDoubleClickProperty = DependencyProperty.RegisterAttached(
            "OnDoubleClick",
            typeof(ICommand),
            typeof(DoubleClickBehavior),
            new UIPropertyMetadata(DoubleClickBehavior.OnDoubleClick));

        public static void SetOnDoubleClick(DependencyObject target, ICommand value)
        {
            target.SetValue(OnDoubleClickProperty, value);
        }

        private static void OnDoubleClick(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            var element = target as Control;
            if (element == null)
            {
                throw new InvalidOperationException("This behavior can be attached to a Control item only.");
            }

            if ((e.NewValue != null) && (e.OldValue == null))
            {
                element.MouseDoubleClick += MouseDoubleClick;
            }
            else if ((e.NewValue == null) && (e.OldValue != null))
            {
                element.MouseDoubleClick -= MouseDoubleClick;
            }
        }

        private static void MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            UIElement element = (UIElement)sender;
            ICommand command = (ICommand)element.GetValue(OnDoubleClickProperty);
            command.Execute(null);
        }

        #endregion DoubleClick
    }

Usage

        <Style   BasedOn="{StaticResource {x:Type DataGridRow}}"
               TargetType="{x:Type DataGridRow}">
            <Setter Property="Helpers:DoubleClickBehavior.OnDoubleClick" Value="{Binding Path=DataContext.MyCommandInVM, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ViewLayer:MyUserControl}}}" />
        </Style>
Community
  • 1
  • 1
Akanksha Gaur
  • 2,636
  • 3
  • 26
  • 50
2

Not sure if you're going the MVVM route, but I've achieved this functionality using an Attached Command Behavior to wire up the double click event to a command in my viewmodel (where "command" is a reference to my attachedCommandBehavior assembly/class):

<DataGrid.RowStyle>
        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="command:CommandBehavior.Event" Value="MouseDoubleClick"/>
            <Setter Property="command:CommandBehavior.Command" Value="{Binding SelectItemCmd}"/>
            <Setter Property="command:CommandBehavior.CommandParameter" Value="{Binding }"/>
        </Style>
</DataGrid.RowStyle>
Paul A
  • 21
  • 2