Reputation: 17905
I created behavior for DataGrid to detect double-click:
public class DataGridDoubleClickBehavior : Behavior<DataGrid>
{
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
"CommandParameter",
typeof(object),
typeof(DataGridDoubleClickBehavior),
new PropertyMetadata(null));
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public static readonly DependencyProperty DoubleClickCommandProperty = DependencyProperty.Register(
"DoubleClickCommand",
typeof(ICommand),
typeof(DataGridDoubleClickBehavior),
new PropertyMetadata(null));
public ICommand DoubleClickCommand
{
get { return (ICommand)GetValue(DoubleClickCommandProperty); }
set { SetValue(DoubleClickCommandProperty, value); }
}
protected override void OnAttached()
{
this.AssociatedObject.LoadingRow += this.OnLoadingRow;
this.AssociatedObject.UnloadingRow += this.OnUnloadingRow;
base.OnAttached();
}
protected override void OnDetaching()
{
this.AssociatedObject.LoadingRow -= this.OnLoadingRow;
this.AssociatedObject.UnloadingRow -= this.OnUnloadingRow;
base.OnDetaching();
}
private void OnLoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.MouseLeftButtonUp += this.OnMouseLeftButtonUp;
}
private void OnUnloadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.MouseLeftButtonUp -= this.OnMouseLeftButtonUp;
}
private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount < 2) return;
if (this.DoubleClickCommand != null) this.DoubleClickCommand.Execute(this.CommandParameter);
}
}
Everything seems to be fine except that it doesn't register multiple clicks. In OnMouseLeftButtonUp
ClickCount always 1. Does anybody know why?
Upvotes: 8
Views: 5333
Reputation: 11287
I found a very simple solution. Just replace the event handler registration syntax
myDataGrid.MouseLeftButtonDown += this.MyDataGrid_MouseLeftButtonDown;
with the AddHandler
syntax
myDataGrid.AddHandler(DataGrid.MouseLeftButtonDownEvent,
new MouseButtonEventHandler(this.MyDataGrid_MouseLeftButtonDown),
handledEventsToo: true)
That way the magic boolean handledEventsToo
argument can be specified.
This will, well, handle handled events too.
Upvotes: 11
Reputation: 36573
MouseButtonUp is broken with respect to capturing ClickCount in WPF and Silverlight (it's been recorded many times but Microsoft has opted not to fix it). You need to use MouseButtonDown events.
Upvotes: 1
Reputation: 1726
I ran into this exact same problem. I couldn't manage to resolve it in any sensible way, so worked around it like this:
private DateTime _lastClickTime;
private WeakReference _lastSender;
private void Row_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var now = DateTime.Now;
if ((now - _lastClickTime).TotalMilliseconds < 200 && _lastSender != null && _lastSender.IsAlive && _lastSender.Target == sender)
{
if (Command != null)
{
Command.Execute(CommandParameter);
}
}
_lastClickTime = now;
_lastSender = new WeakReference(sender);
}
It's dirty but it works.
Upvotes: 0
Reputation: 7323
Well, the bigger trouble here is that when you click on the rows of a DataGrid, MouseLeftButtonDown is not raised, because this click is being handled at the row level.
I've long given up on dealing with some controls directly. I've my own derived version of the DataGrid, DataForm and etc. This only makes my solution easy to roll out, because I don't use the vanilla versions anyway.
I added a new event called ClickIncludingHandled, it's a bit wordy but it properly describes what's going on and will nicely appear right below Click with IntelliSense - if the control has a Click event to begin with.
Anyway, below is my implementation of it. You can then subscribe to this event and use ClickCount to determine the number of clicks you want to capture. I noticed it is a bit slow, but it works cleanly.
public partial class DataGridBase : DataGrid
{
public event MouseButtonEventHandler ClickIncludingHandled;
public DataGridBase() : base()
{
this.AddHandler(MouseLeftButtonDownEvent, new MouseButtonEventHandler(OnClickInclHandled), true);
}
private void OnClickInclHandled(object sender, MouseButtonEventArgs e)
{
if (ClickIncludingHandled != null)
{
ClickIncludingHandled(sender, e);
}
}
}
Upvotes: 3
Reputation: 13579
Not 100% sure this is the issue, but I notice that Pete Brown's sample uses MouseLeftButtonDown instead:
http://10rem.net/blog/2011/04/13/silverlight-5-supporting-double-and-even-triple-click-for-the-mouse
Upvotes: 0