Search code examples
c#wpfeventscanvasdraggable

Mouse event not working twice


I encounter a strange problem. I've got a canvas and drawed a complexe structure: an Image inside a Grid inside a Border. My Image is the one which is active for moving.

It works well the first time i drag my structure but the second time nothing works at all no exception but nothing works. It seems to me to be a problem of mouse capture but i can't catch what's about.

Here is my event code :

bool captured = false;
double x_shape, x_canvas, y_shape, y_canvas;
double x_shape_Origine, y_shape_Origine;
Border source = null;


int CountZ = 10;

private void shape_MoveButtonDown(object sender, MouseButtonEventArgs e)
{
    /// AWFULLY SOURCE WAS null. I don't understand Why it was working the    
    /// first time
    Mouse.Capture(source);
    captured = true;

    Image myImage = (Image)sender;
    Grid outerGrid = (Grid)myImage.Parent;
    source = (Border)outerGrid.Parent;

    Canvas.SetZIndex(source, CountZ++);
    x_shape = Canvas.GetLeft(source);
    y_shape = Canvas.GetTop(source);

    x_canvas = e.GetPosition(myCanvas).X;
    y_canvas = e.GetPosition(myCanvas).Y;

}


private void shape_MoveMoving(object sender, MouseEventArgs e)
{
    if (captured)
    {
        double x = e.GetPosition(myCanvas).X;
        double y = e.GetPosition(myCanvas).Y;
        x_shape += x - x_canvas;
        Canvas.SetLeft(source, x_shape);
        x_canvas = x;
        y_shape += y - y_canvas;
        Canvas.SetTop(source, y_shape);
        y_canvas = y;
    }
}

private void shape_MoveButtonUp(object sender, MouseButtonEventArgs e)
{
    Mouse.Capture(null);
    captured = false;

}

private void shape_MouseEnter(object sender, MouseEventArgs e)
{
    if (!captured)
    {
        Border inner = (Border)sender;
        Grid parentInner = (Grid)inner.Parent;

        parentInner.Children[0].Visibility = Visibility.Visible;
        parentInner.Children[2].Visibility = Visibility.Visible;
        parentInner.Children[5].Visibility = Visibility.Visible;
        parentInner.Children[6].Visibility = Visibility.Visible;
        parentInner.Children[8].Visibility = Visibility.Visible;

        parentInner.Background = new SolidColorBrush(Colors.Red);
    }
}

private void shape_MouseLeave(object sender, MouseEventArgs e)
{
    if (!captured)
    {
        Grid outer = (Grid)sender;

        outer.Children[0].Visibility = Visibility.Hidden;
        outer.Children[2].Visibility = Visibility.Hidden;
        outer.Children[5].Visibility = Visibility.Hidden;
        outer.Children[6].Visibility = Visibility.Hidden;
        outer.Children[8].Visibility = Visibility.Hidden;

        outer.Background = null;
    }
}

Hope it will make sense for you


Solution

  • I had a complete sample for D&D with WPF and Silverlight. Here full code, hope it helps.

    class MyWnd : Window
    {       
        public MyWnd()
        {
            var c = new Canvas();
            c.Background = new SolidColorBrush(Colors.White);
    
            var rect = new Rectangle { Fill = new SolidColorBrush(Colors.Red), Width = 20, Height = 20 };
            c.Children.Add(rect);
    
            this.Content = c;
    
            Canvas.SetLeft(rect, 0);
            Canvas.SetTop(rect, 0);
    
            rect.MouseLeftButtonDown+=Handle_MouseDown;
            rect.MouseLeftButtonUp+=Handle_MouseUp;
            rect.MouseMove+=Handle_MouseMove;
        }
    
    
        bool isMouseCaptured;
        double mouseVerticalPosition;
        double mouseHorizontalPosition;
    
        public void Handle_MouseDown(object sender, MouseEventArgs args)
        {
            var item = sender as FrameworkElement;
            mouseVerticalPosition = args.GetPosition(null).Y;
            mouseHorizontalPosition = args.GetPosition(null).X;
            isMouseCaptured = true;
            item.CaptureMouse();
        }
    
        public void Handle_MouseMove(object sender, MouseEventArgs args)
        {
            var item = sender as FrameworkElement;
            if (isMouseCaptured)
            {
    
                // Calculate the current position of the object.
                double deltaV = args.GetPosition(null).Y - mouseVerticalPosition;
                double deltaH = args.GetPosition(null).X - mouseHorizontalPosition;
                double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty);
                double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty);
    
                // Set new position of object.
                item.SetValue(Canvas.TopProperty, newTop);
                item.SetValue(Canvas.LeftProperty, newLeft);
    
                // Update position global variables.
                mouseVerticalPosition = args.GetPosition(null).Y;
                mouseHorizontalPosition = args.GetPosition(null).X;
            }
        }
    
        public void Handle_MouseUp(object sender, MouseEventArgs args)
        {
            var item = sender as FrameworkElement;
            isMouseCaptured = false;
            item.ReleaseMouseCapture();
            mouseVerticalPosition = -1;
            mouseHorizontalPosition = -1;
        }
    }
    
    void Main()
    {
        var wnd = new MyWnd();
        wnd.ShowDialog();
    }