WPF: How to draw a circle and drag it around?
Asked Answered
Q

4

7

I am new to WPF.

I want to draw a small circle on Canvas when I click mouse and be able to drag it around smoothly.

How can I accomplish this?

Quint answered 23/9, 2009 at 10:30 Comment(0)
W
3

"whatever it is" matters because placement of elements in WPF is highly dependent on the parent container. It's easy to move something 20px to the right inside a Canvas (just add to Canvas.Left), but it's much harder to do so in a Grid (you have to deal with Column, ColumnSpan and Margin).

There's a code project article describing how to drag elements inside a Canvas: Dragging Elements in a Canvas

If you want to move just that circle and not other controls in an existing Canvas/Grid; I suggest you use a DragCanvas (from the article) as an overlay over the normal Canvas/Grid.

As for the 'draw a circle' part: just use an Ellipse as element inside the DragCanvas.

Wunderlich answered 23/9, 2009 at 10:38 Comment(1)
Ok. I am using Canvas and done with drawing but dragging is still a problem. Can you provide small code snippet?Quint
P
3

I would define a canvas and an ellipse in the XAML file:

<Canvas Background="White" Name="canvas" Width="950" Height="500" MouseDown="MouseMove">
    <Ellipse Name="bola" Canvas.Left="130" Canvas.Top="79" Width="50" Height="50" Fill="Green"  />
</Canvas>

Notice that canvas has the attribute MouseDown="MouseMoveFunction". Whenever you click on the canvas, that event handler will be called. In case you want it to move as your mouse moves, use MouseMove="MouseMoveFunction"

Then just update the ellipse's position everytime you move your mouse. The following code goes in the function that is called on mouse events:

    private void MouseMove(object sender, MouseEventArgs e)
    {
        Point punto = e.GetPosition(canvas);
        int mouseX = (int)punto.X;
        int mouseY = (int)punto.Y;
        bola.SetValue(Canvas.LeftProperty, (double)mouseX); //set x
        bola.SetValue(Canvas.TopProperty, (double)mouseY); //set y

    }
Prizewinner answered 20/3, 2012 at 22:54 Comment(2)
FYI - That code in the MouseMove doesn't quite work. I put the code in my WPF app and debugged it. I can see each of the lines stepped onto but the Ellipse is never redrawn in the new location. Is there some way to call Invalidate() on the canvas rect or something? Not sure, but this doesn't work.Copenhagen
Note: If the canvas doesn't have background color, mousemove and click wont register there. (so i placed my mousemove event to the image behind invisible canvas)Grub
C
1

I was able to do this all in code, but unable to move the Ellipse element that was a child element of my canvas.

I've copied the code below so you can reproduce it.
First create a WPF app called WPFExample and make sure your main form has the following:

<Window x:Class="WPFExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFExample"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" Background="LightGray">
    <Grid>
        <Canvas HorizontalAlignment="Left" Name="MainCanvas"
                Height="300" Width="500" Margin="5,5,5,5" VerticalAlignment="Top" Background="LightYellow" MouseDown="Canvas_MouseDown" MouseMove="MainCanvas_MouseMove"
                />
        <Ellipse Name="post" Width="50" Height="50" Fill="Red" Margin="5,5,5,5"  />

    </Grid>
</Window>

Next, add the code to your main form:

       private void Draw(Point m)
        {
            MainCanvas.Children.Clear();

            int mX = (int)m.X;
            int mY = (int)m.Y;
            Ellipse el = new Ellipse();
            el.Width = 15;
            el.Height = 15;
            el.SetValue(Canvas.LeftProperty, (Double)mX);
            el.SetValue(Canvas.TopProperty, (Double)mY);
            el.Fill = Brushes.Black;

            MainCanvas.Children.Add(el);
        }

        private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Draw(e.GetPosition(MainCanvas));
        }

        private void MainCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            Draw(e.GetPosition(MainCanvas));
        }

Obviously, focus on the Draw() method. Notice that I Clear the canvas each time through. Then I draw the new Ellipse in the mouse location as a black circle.

Now each time you move your mouse the black circle is erased from the canvas, created again and then drawn in the new location. Here's a snapshot of the app -- when you run it and move the mouse the black circle will be redrawn wherever you move your mouse, as if you are dragging it around. black circle redraw

The red ellipse was problematic for me and I could never get it to redraw and couldn't remove it from the list of children and add it again for this quick example.

Copenhagen answered 1/9, 2016 at 19:33 Comment(0)
A
0

I have an example blog post of drag and drop of a rectangle in a WPF environment, but using the MVVM architecture. The contents are too lengthy to reproduce here, but the instructions should be fairly simple.

It should also be fairly straightforward to replace the rectangle with an ellipse or other shapes of your own.

drag and drop rectangle in WPF / MVVM

Annals answered 3/1, 2020 at 23:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.