Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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

    }

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top