Basically, you have no solution other than using the TemplateColumn and managing each individual mouse user.
Explanation:
click = mouseDown + MouseUp , on the right. therefore, your button should be able to receive the mouseDown + MouseUp event.
BUT...
by default, wpf DataGrid has its own rows that handle the mouseDown event to select the one you use mouseDown on (to confirm: mouseDown on the cell and hold the mouse button, you will see that the row is selected before you release the button).
So basically, MouseDownEvent processed before it reaches the button, which allows you to use the Click event on the button
Microsoft will tell us in its document that in such cases we should refer to the preview event, but this cannot be applied to the click event, since you cannot have PreviewClickEvent
So, the only solution that I see for you is to listen to both PreviewMouseDown and PreviewMouseUp on your button and simulate the click yourself.
something like that:
Button myButton = new Button(); bool mouseLeftButtonDownOnMyButton; myButton.PreviewMouseLeftButtonDown += (s, e) => { mouseLeftButtonDownOnMyButton = true; }; myButton.PreviewMouseLeftButtonUp += (s, e) => { if (mouseLeftButtonDownOnMyButton) myButton.RaiseEvent( new RoutedEventArgs(Button.ClickEvent,myButton)); mouseLeftButtonDownOnMyButton = false; }; myButton.Click += myButtonCLickHandler;
(of course you need to translate this into your xaml template)
NB: this is not complete, you should also take care of cases when the user makes mouseDown on the button, but moves the mouse out of the button before making a hint (in this case, you must reset the mouseLeftButtonDownOnMyButton flag). The best way would probably be to reset the flag in the general mouseUpEvent (e.g. at window level) rather than in a single button.
Edit: the above code also allows you to control the Click event and have only one code for real and simulated click events (hence the RaiseEvent method), but if you need it, you can also specify your code directly in the PreviewMouseUp section.