Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 669
Pratik Deoghare Avatar asked Sep 23 '09 10:09

Pratik Deoghare


People also ask

How do you draw a circle in WPF?

Use its Stroke property to specify the Brush that is used to paint the outline of the ellipse. The StrokeThickness property specifies the thickness of the ellipse outline. To draw a circle, make the Width and Height of the Ellipse element equal to each other.

How to make circle in xaml?

So how can we make one in XAML without acutally cropping the image? It's simple. First, use "ellipse" to draw a circle, make it's width equal to height, that makes a circle. Ellipse has many options on "Fill", such as solid color, gradient color, image, and web.

How do you draw a straight line in WPF?

To draw a line, create a Line element. Use its X1 and Y1 properties to set its start point; and use its X2 and Y2 properties to set its end point. Finally, set its Stroke and StrokeThickness because a line without a stroke is invisible. Setting the Fill element for a line has no effect, because a line has no interior.

How do you draw a rectangle in WPF?

To draw a rectangle, create a Rectangle element and specify its Width and Height. To paint the inside of the rectangle, set its Fill. To give the rectangle an outline, use its Stroke and StrokeThickness properties. To give the rectangle rounded corners, specify the optional RadiusX and RadiusY properties.


3 Answers

"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.

like image 183
Daniel Avatar answered Sep 29 '22 13:09

Daniel


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

    }
like image 38
fersarr Avatar answered Sep 29 '22 12:09

fersarr


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.

like image 28
raddevus Avatar answered Sep 29 '22 13:09

raddevus