In WPF most controls have MouseUp and MouseDown events (and the mouse-button-specific variations) but not a simple Click event that ca
Here is a behavior you can add to any element so that it will raise the ButtonBase.Click event using the normal button logic:
public class ClickBehavior : Behavior
{
protected override void OnAttached()
{
AssociatedObject.MouseLeftButtonDown += (s, e) =>
{
e.Handled = true;
AssociatedObject.CaptureMouse();
};
AssociatedObject.MouseLeftButtonUp += (s, e) =>
{
if (!AssociatedObject.IsMouseCaptured) return;
e.Handled = true;
AssociatedObject.ReleaseMouseCapture();
if (AssociatedObject.InputHitTest(e.GetPosition(AssociatedObject)) != null)
AssociatedObject.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
};
}
}
Notice the use of mouse capture/release and the input hit test check. With this behavior in place, we can write click handlers like this:
and the code behind:
private void Rectangle_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Code-behind: Click");
}
It's easy enough to convert this to all code-behind; the important part is the capture and click logic.
If you are not familiar with behaviors, install the Expression Blend 4 SDK and add this namespace:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
and add System.Windows.Interactivity to your project.
Edit:
Here's how to attach the click behavior to an element in code-behind and add a handler for the click event:
void AttachClickBehaviors()
{
AttachClickBehavior(rectangle1, new RoutedEventHandler(OnAttachedClick));
}
void OnAttachedClick(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Attached: Click");
}
// Reusable: doesn't need to be in the code-behind.
static void AttachClickBehavior(FrameworkElement element, RoutedEventHandler clickHandler)
{
Interaction.GetBehaviors(element).Add(new ClickBehavior());
element.AddHandler(ButtonBase.ClickEvent, clickHandler);
}