Last week I was faced with a problem. I needed to implement a MouseDoubleClick Event on a WPF Grid. I said Ha, easy, but as i went on to implement it i realized that the Grid has no MouseDoubleClick Event! So how am I supposed to implement it? I came up with 2 solutions so here goes:

  1. the first thought i had was to create a User Control that held only a grid and implement the MouseDoubleClick on the User Control itself so what you will get is this Xaml code:
  2. <UserControl x:Class="CustomDoubleClick.GridWrapper"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="300" Width="300">
        <Grid>
    
        </Grid>
    </UserControl>
    Since the Grid takes the entire space of the control if you implement a MouseDoubleClick event on the control:
    public partial class GridWrapper : UserControl
        {
            public GridWrapper()
            {
                InitializeComponent();
                this.MouseDoubleClick +=
                      new MouseButtonEventHandler(GridWrapper_MouseDoubleClick);
            }
    
            void GridWrapper_MouseDoubleClick(object sender, MouseButtonEventArgs e)
            {
                throw new NotImplementedException();
            }
        }
    What you got is a WPF Grid with a MouseDoubleClick Event.
     
  3. I like This method better because it uses the power of WPF ControlTemplates. We need a WPF Grid with a MouseDoubleClick Event, which control has a MouseDoubleClick Event? a Button… So we want a Button that looks like a Grid. No problem all we need is to create a Style with Control Template to the Button:
  4. <Window x:Class="CustomDoubleClick.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:this="clr-namespace:CustomDoubleClick"
        Title="Window1" Height="300" Width="300">
        <Window.Resources>
            <Style TargetType="{x:Type Button}" x:Key="GridButton">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Grid Background="{TemplateBinding Property=Background}"
                                  Width="{TemplateBinding Property=Width}"
                                  Height="{TemplateBinding Property=Height}">
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Window.Resources>
        <Canvas>
            <Button Style="{StaticResource GridButton}" Width="200" Height="200"
                    Background="Red" MouseDoubleClick="Button_MouseDoubleClick">
            </Button>
        </Canvas>
    </Window>
     
    And once again you get a Grid with a MouseDoubleClick Event. You can use this method to add double click to any WPF control in the toolbox.
     
    Do you know of a different way to do this? If so, please comment.
     
    Amit

Tags :

9 Responses to “How To Add a MouseDoubleClick Event To Any WPF Control”


  1. Derek Lakin

    Said on May 14, 2008 :

    You could just handle the MouseDown event for whichever control you have that doesn’t support double-clicks (like Grid) and check to see whether the ClickCount property in the MouseButtonEventArgs is 2 (or more if you like!):

    private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
    {
    if (e.ClickCount >= 2)
    {
    // Do whatever you want in response to a double click.
    }
    }

    Seems like a quicker and easier way to handle double-clicks ;)

  2. Shahar Y

    Said on May 14, 2008 :

    Hi Derek Lakin,

    That is really another great option to handle the problem. But the condition should be: if (e.ClickCount >= 2 && e.LeftButton == MouseButtonState.Pressed). Otherwise, right clicks and any other mouse clicks will count too.
    Thanks.

  3. David N

    Said on May 14, 2008 :

    You can also do this by adding an InputBinding to the Grid, that will translate a double click to an invocation of a RoutedCommand, then you can bind that to some handler code somewhere higher in the tree. Commands seem to be a neglected part of WPF, but are really quite useful especially if there are multiple actions that should end up triggering the same code (button, toolbar button, context menu, key combination, double click in the grid..). I just used a builtin command in this sample but of course you’d probably use a custom one.

  4. Amit

    Said on May 15, 2008 :

    @ David

    I will try you solution and if it works you will earn a big credit in my next post because it is a great solution. I use Commands all the time as they are so comfortable.

    @ Derek
    I am femiliar with your solution and have used it before, but it can give you a lot of trouble when you interop with WinForms. It also makes Debuging a bit hard because if you have a break point the second click will not be registered

    Amit

  5. Michael H

    Said on July 21, 2008 :

    I have tried Derek’s approach on CheckBox and it didn’t work entirely.

    First off the CheckBox is doing something with the Click Event so if you want to do a MouseUp or MouseDown it is ignored unless you do the PreviewMouseUp or PreviewMouseDown.

    To add to Derek’s suggestion there is a MouseLeftButtonDown and MouseLeftButtonUp as well as a PreviewMouseLeftButtonDown and PreviewMouseLeftButtonUp so you don’t have to do the “IF” statement.

    The problem exists in that you do a PreviewMouseDown or PreviewMouseUp and lets say you want the CheckBox to be checked when this happens. Once that code execution is completed and the Box is checked you will find that the CheckBoxes own Click event is fired and it will deselect the box.

    You can override the CheckBox to get around this but it just seems like it is going too far to fix this problem… this should be easier.

    PS one more comment. I noticed you are doing a e.ClickCount == 2. In my opinion this should be done on MouseUp and not on the MouseDown event however if you were to try this you would find that the ClickCount is not populated correctly on the MouseUp. I am finding many little things like this frustrating about the whole WPF world.

  6. andrewjs

    Said on May 19, 2009 :

    I created an attached property to handle double clicks on items. Here’s a code snippet (which I’ll generalise when I need to, but you should get the idea):

    public class ControlItemDoubleClick : DependencyObject
    {
    public ControlItemDoubleClick()
    {

    }

    public static readonly DependencyProperty ItemsDoubleClickProperty =
    DependencyProperty.RegisterAttached(“ItemsDoubleClick”,
    typeof(bool), typeof(Binding));

    public static void SetItemsDoubleClick(ItemsControl element, bool value)
    {
    element.SetValue(ItemsDoubleClickProperty, value);

    if (value)
    {
    element.PreviewMouseDoubleClick += new MouseButtonEventHandler(element_PreviewMouseDoubleClick);
    }
    }

    static void element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
    ItemsControl control = sender as ItemsControl;

    foreach (InputBinding b in control.InputBindings)
    {
    if (!(b is MouseBinding))
    {
    continue;
    }

    if (b.Gesture != null
    && b.Gesture is MouseGesture
    && ((MouseGesture)b.Gesture).MouseAction == MouseAction.LeftDoubleClick
    && b.Command.CanExecute(null))
    {
    b.Command.Execute(null);
    e.Handled = true;
    }
    }
    }

    public static bool GetItemsDoubleClick(ItemsControl element)
    {
    return (bool)element.GetValue(ItemsDoubleClickProperty);
    }
    }

  7. Sam Meldrum

    Said on August 12, 2009 :

    These solutions are all a bit complicated and have other drawbacks.

    You can juist place the Grid inside a ContentControl and attach to the ContentControl’s MouseDoubleClick event.

    Much simpler.

2 Trackback(s)

  1. May 14, 2008: Dew Drop - May 14, 2008 | Alvin Ashcraft's Morning Dew
  2. May 15, 2008: Paul’s Page » Blog Archive » How To Add a MouseDoubleClick Event To Any WPF Control

Post a Comment