BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Windows Presentation Foundation
.NET 4.0+

WPF Base Classes - UIElement - Mouse Events

The twenty-third instalment of the Windows Presentation Foundation Fundamentals tutorial continues the examination of the UIElement class, which is a superclass of all WPF layout controls, as well as other WPF controls. This article is about mouse events.

Locating the Mouse Pointer

Often you will need to find the position of the mouse pointer when an event occurs. For example, you might be developing an image editing application, where knowing the location of the mouse within a drawing is essential to the program's correct operation. For this you can use the GetPosition method.

GetPosition allows you to obtain the mouse pointer's location relative to any control. Often this will be the control for which the event is declared or for one of the manipulated control's parents. You specify the control for which to provide co-ordinates in the method's argument. The parameter expects an object of the IInputElement type. All controls implement this interface. The return value is a Point. This has X and Y properties that hold the co-ordinates relative to the top left of the control.

To demonstrate, modify the MouseMove event code as shown below. Here the position of the mouse pointer relative to the StackPanel and the Window are both outputted each time the mouse is moved within the StackPanel's area. As the event is raised by the StackPanel, the StackPanel object is passed to the method in the sender parameter. As this is defined as an object, explicit casting to IInputElement is necessary.

private void StackPanel_MouseMove(object sender, MouseEventArgs e)
{
    Debug.WriteLine("Move");

    Point spRel = e.GetPosition((IInputElement)e.OriginalSource);
    Debug.WriteLine("* StackPanel: ({0},{1})", spRel.X, spRel.Y);

    Point winRel = e.GetPosition(this);
    Debug.WriteLine("* Window:     ({0},{1})", winRel.X, winRel.Y);
}

Preventing Routing of Mouse Events

In the article describing the UIElement keyboard events I mentioned the Handled property provided by KeyEventArgs. If you set this Boolean property to true, further routing of the event is prevented. This means that a single event that might be handled by many controls in the logical tree can be prevented from further bubbling.

MouseEventArgs also provides a Handled property that operates in much the same way. For example, if we had registered the MouseDown event for both the StackPanel and the Window, setting the property to true in the StackPanel's event handler would prevent the Window's method from running. Furthermore, some events share event arguments. This means that one event can effectively cancel another. This is useful is situations where you know that an event being handled at one position in the code ensures that no further processing is required.

To demonstrate, we'll see the interaction between the MouseDown and MouseLeftButtonDown events. At the moment when you press the left button you should see the following messages:

Left Button Down
Mouse Down
* Left: Pressed
* Middle: Released
* Right: Released
* X1: Released
* X2: Released

If we know that the MouseLeftButtonDown performs all required actions, rendering the execution of MouseDown unnecessary, we could set the Handled property within the StackPanel_MouseLeftButtonDown method, as follows:

private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Debug.WriteLine("Left Button Down - MouseDown Cancelled");
    e.Handled = true;
}

Now clicking the left button will only show the following message:

Left Button Down - MouseDown Cancelled

The MouseDown event will continue to fire for any other button click. For example, right-clicking the StackPanel gives the following output:

Right Button Down
Mouse Down
* Left: Released
* Middle: Released
* Right: Pressed
* X1: Released
* X2: Released
4 August 2013