GreenEyedAndy
GreenEyedAndy

Reputation: 1525

MouseEventArgs.GetPosition not working as expected in WPF

I would try a little Shapemoving and wrote the following Application:

<Window x:Class="WpfApplication7.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
  <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="27" />
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <ToolBar Grid.Row="0"/>
    <Canvas Grid.Row="1" MouseDown="OnMouseDown" MouseUp="OnMouseUp" MouseMove="OnMouseMove">
        <Ellipse Width="100" Height="100" Fill="Red" Canvas.Left="50" Canvas.Top="50" />
        <Ellipse Width="100" Height="100" Fill="Red" Canvas.Left="180" Canvas.Top="50" />
        <Rectangle Width="100" Height="100" Fill="Blue" Canvas.Left="220" Canvas.Top="160" />
    </Canvas>
  </Grid>
</Window>

and the Code behind:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApplication7
{
  public partial class MainWindow
  {
    private UIElement SelectedObject { get; set; }
    private bool captureMouse;
    private Point diffPosition;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void OnMouseDown(object sender, MouseButtonEventArgs e)
    {
        SelectedObject = e.Source as UIElement;
        if (SelectedObject != null)
        {
            captureMouse = SelectedObject.CaptureMouse();
            diffPosition = e.GetPosition(SelectedObject);
        }
    }

    private void OnMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (captureMouse)
        {
            SelectedObject.ReleaseMouseCapture();
        }
        SelectedObject = null;
    }

    private void OnMouseMove(object sender, MouseEventArgs e)
    {
        if (SelectedObject != null)
        {
            Canvas.SetLeft(SelectedObject, e.GetPosition(this).X - diffPosition.X);
            Canvas.SetTop(SelectedObject, e.GetPosition(this).Y - diffPosition.Y);
        }
    }
  }
}

I thought getting the diffPosition of the Click-Point in OnMouseDown with GetPosition relative to SelectedObject save me a few lines of code, but the height of the Toolbar is added. So my Y-Coordinate is 27 pixel more than I expected. If I delete the Toolbar, all works well. What do I have to do to get the correct offset with the Toolbar in the Form?

I know it's just a little mistake, but I can't find it.

Upvotes: 3

Views: 8016

Answers (1)

Bizhan
Bizhan

Reputation: 17085

Name your drawing area:

 <Canvas Grid.Row="1" x:Name="drawingArea" ...>
    ...
 </Canvas>

and compare positions with drawingArea's.

e.GetPosition(this.drawingArea)

This way you don't need to worry about layout changes and etc.

Upvotes: 1

Related Questions