简体   繁体   English

WPF:如何画一个圆圈并拖动它?

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

I am new to WPF.我是 WPF 的新手。

I want to draw a small circle on Canvas when I click mouse and be able to drag it around smoothly .我想在单击鼠标时在 Canvas 上画一个小圆圈并能够平滑地拖动它

How can I accomplish this?我怎样才能做到这一点?

"whatever it is" matters because placement of elements in WPF is highly dependent on the parent container. “不管它是什么”很重要,因为 WPF 中元素的放置高度依赖于父容器。 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).在 Canvas 内将某些东西向右移动 20px 很容易(只需添加到 Canvas.Left),但在 Grid 中这样做要困难得多(您必须处理 Column、ColumnSpan 和 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.我建议您使用 DragCanvas(来自文章)作为普通 Canvas/Grid 的叠加。

As for the 'draw a circle' part: just use an Ellipse as element inside the DragCanvas.至于“画圆”部分:只需在 DragCanvas 中使用 Ellipse 作为元素。

I would define a canvas and an ellipse in the XAML file:我会在 XAML 文件中定义一个画布和一个椭圆:

<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" .请注意,画布具有属性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"如果您希望它随着鼠标移动而移动,请使用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.我能够在代码中完成这一切,但无法移动作为画布子元素的 Ellipse 元素。

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:首先创建一个名为 WPFExample 的 WPF 应用程序,并确保您的主表单具有以下内容:

<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.显然,重点放在Draw()方法上。 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.这是该应用程序的快照——当您运行它并移动鼠标时,无论您移动鼠标的位置,都会重新绘制黑色圆圈,就好像您正在拖动它一样。 黑圈重绘

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.红色椭圆对我来说是有问题的,我永远无法重绘它,也无法将它从子项列表中删除并为这个快速示例再次添加它。

I have an example blog post of drag and drop of a rectangle in a WPF environment, but using the MVVM architecture.我有一个在 WPF 环境中拖放矩形的示例博客文章,但使用的是 MVVM 架构。 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 在 WPF/MVVM 中拖放矩形

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM