[.net] Desperate! WPF // move object on canvas ...

Started by
3 comments, last by ernow 14 years ago
hi guys, i'm desperatly trying to move a shape on a canvas with the mouse!! it does not work quite good. when i click on the left mouse button, i want my shape to move along with my pointer. Here are my functions, i tryed to follow this : http://stackoverflow.com/questions/437639/how-do-i-use-capturemouse-or-mouse-capture-in-my-c-wpf-application So, when my left button is down, i capture the mouse for the shape :

       private void canvas1_MouseLeftButtonDown(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Console.WriteLine("down");
            Canvas canvas = (Canvas)sender;
            Point p = e.GetPosition(canvas);
            for (int index = 0; index < VisualTreeHelper.GetChildrenCount((DependencyObject)canvas); index++)
            {
                if ( VisualTreeHelper.HitTest(canvas,p) != null) 
                {                    
                    Shape shape = VisualTreeHelper.GetChild(canvas, index) as Shape;
                    Console.WriteLine("capture {0}", shape.ToString());
                    shape.MouseMove += new System.Windows.Input.MouseEventHandler(shape_MouseMove);
                    shape.CaptureMouse();
                }
            }
            
        }



When the mouse moves, i check if the object is captured (the shape), and if so, i redraw the content :

        private void shape_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Shape s = sender as Shape;
            if (s.IsMouseCaptured == true)
            {
                Point p = e.GetPosition((IInputElement)sender);
                Console.WriteLine("{0} -- {1} -- {2}", s.ToString(), p.ToString(), s.Parent.ToString());
                Canvas canvas = s.Parent as Canvas;

                canvas.Children.Remove(s);
                Canvas.SetTop(s, p.Y);
                Canvas.SetLeft(s, p.X);
                canvas.Children.Add(s);
            }
        }



Finally, when my left mouse button is up again, i release the mouse capture for the shape:

        private void canvas1_MouseLeftButtonUp(object sender, System.Windows.Input.MouseEventArgs e)
        {
            for (int index = 0; index < VisualTreeHelper.GetChildrenCount((DependencyObject)sender); index++)
            {
                Shape s = VisualTreeHelper.GetChild((DependencyObject)sender, index) as Shape;
                if (s.IsMouseCaptured == true)
                {
                    Console.WriteLine("release");
                    s.ReleaseMouseCapture();
                }
            }
        }



However, i kind of works but the movement of the shape is jiggly, it seems to be in conflit with something. As a result, the object shape follows my mouse pointer but it constantly jumps to other random locations on the canvas .... What is wrong ?? please help me!! :) cheers
Advertisement
My guess is that because you are removing and adding the shape while the shape is capturing the mousemove causes the errors.

Don't worry about the mouse move on the shape, focus on the mouse move on the canvas.

See this
hello!

thanks for the link

Quote:
Don't worry about the mouse move on the shape, focus on the mouse move on the canvas.


indeed! The error came from shape_MouseMove(), where is used the shape coordinate instead of the canvas.

here is my corrected function:

 private void shape_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)        {            Shape s = sender as Shape;            if (s.IsMouseCaptured == true)            {                Canvas canvas = s.Parent as Canvas;                Point p = e.GetPosition((IInputElement)canvas); //CORRECTION HERE                canvas.Children.Remove(s);                Canvas.SetTop(s, p.Y);                Canvas.SetLeft(s, p.X);                canvas.Children.Add(s);            }        }


cheers
uuuuppp!!!!

Sorry again, but i have another problem...

I want to be able to click on several shapes. However, it seems all my shapes are bound together, sort of. So when i click on a shape, then i want to click on another, i always have the focus on the first shaped i clicked on but not the new one....how is that possible ?

Here is my code again (latest version):

    private void canvas1_MouseLeftButtonDown(object sender, System.Windows.Input.MouseEventArgs e)        {/* when the left button is down, select the shape on the canvas and do a mouse capture on it */            Canvas canvas = (Canvas)sender;            //Console.WriteLine(p.ToString());            for (int index = 0; index < VisualTreeHelper.GetChildrenCount((DependencyObject)canvas); index++)            {                Shape shape = VisualTreeHelper.GetChild(canvas, index) as Shape;                Point p = e.GetPosition(canvas);                                if ( VisualTreeHelper.HitTest(canvas,p) != null)                 {                    Console.WriteLine("hit test ok");                    shape.MouseMove += new System.Windows.Input.MouseEventHandler(shape_MouseMove);                    shape.CaptureMouse();                }            }        }        private void shape_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)        {/* when the mouse moves, and the shape is mouse captured, perform refresh (e.g. update positions) */            Shape s = sender as Shape;            Canvas canvas = s.Parent as Canvas;            Point p = e.GetPosition(canvas);            if (s.IsMouseCaptured == true)            {                canvas.Children.Remove(s);                Canvas.SetTop(s, p.Y);                Canvas.SetLeft(s, p.X);                canvas.Children.Add(s);            }        }        private void canvas1_MouseLeftButtonUp(object sender, System.Windows.Input.MouseEventArgs e)        {/* when the left button is up, release the shape's mouse capture */            for (int index = 0; index < VisualTreeHelper.GetChildrenCount((DependencyObject)sender); index++)            {                Shape s = VisualTreeHelper.GetChild((DependencyObject)sender, index) as Shape;                if (s.IsMouseCaptured == true)                {                    Console.WriteLine("release");                    s.MouseMove -= new System.Windows.Input.MouseEventHandler(shape_MouseMove);                    s.ReleaseMouseCapture();                }            }        }


thank you :/

[Edited by - carmellose on March 19, 2010 9:19:23 AM]
It sound as if the first shape is still capturing the mouse events. When you look at the output of the debug window, is it capturing and releasing correctly?

This topic is closed to new replies.

Advertisement