拖动对象时抖动

Shaking in dragging object

我是 C# 新手。 我一直在使用 MouseDown 和 MouseMove 在 C# (wpf) 中进行测试。尝试创建一个简单的椭圆,可以在 canvas 内通过单击和移动鼠标进行拖动。 一切都很好,直到我 运行 代码并且我看到当我拖动椭圆时它会摇晃。 我知道对某些人来说这不是问题,但对我来说却是。 接下来是我使用的 xaml 中的代码。

<Canvas>
        <Ellipse x:Name="circulito" Fill="#FFFDC347" Height="100" Stroke="Black"  Width="100"
        MouseDown="circulito_MouseDown"
        MouseMove="circulito_MouseMove"/>
</Canvas>

接下来是c#中的代码。

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        Point coor;
        Point coorPutin;

        private void circulito_MouseDown(object sender, MouseButtonEventArgs e)
        {
            coor.X = Canvas.GetLeft(this);
            coor.Y = Canvas.GetTop(this);
        }

        private void circulito_MouseMove(object sender, MouseEventArgs e)
        {            
            coorPutin = e.GetPosition(circulito);                        

            if (Mouse.LeftButton == MouseButtonState.Pressed)
            {
                Canvas.SetLeft(circulito, coor.X + coorPutin.X);
                Canvas.SetTop(circulito, coor.Y + coorPutin.Y);
            }
        }

All good until I run the code and I see that when I drag the ellipse it shakes

这是因为您的 circulito_MouseMove 例程。您不需要检查按钮是否按下,您也在尝试设置 canvas,这不会起作用,您需要设置元素(椭圆)TopPropertyLeftProperty.请参阅下面的工作解决方案。

MainWindow.xaml.cs

public partial class MainWindow : Window
    {
        private Ellipse _ellipse;
        private Point? _coor;

        public MainWindow() { InitializeComponent(); }

        private void circulito_MouseDown(object sender, MouseButtonEventArgs e)
        {
            _ellipse = sender as Ellipse;
            _coor = e.GetPosition(_ellipse);
        }

        private void circulito_MouseMove(object sender, MouseEventArgs e)
        {
            if (_ellipse == null)
                return;

            _ellipse.SetValue(Canvas.LeftProperty, e.GetPosition(this).X - _coor.Value.X);
            _ellipse.SetValue(Canvas.TopProperty, e.GetPosition(this).Y - _coor.Value.Y);
        }

        private void circulito_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) => _ellipse = null;

    }

MainWindow.xaml

<Window x:Class="WpfApp12.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"
        Title="MainWindow"
        Width="800"
        Height="450"
        mc:Ignorable="d"
        MouseMove="circulito_MouseMove"
        >
    <Canvas>
        <Ellipse x:Name="circulito"
                 Width="100"
                 Height="100"
                 Fill="#FFFDC347"
                 Stroke="Black"
                 MouseLeftButtonDown="circulito_MouseDown"
                 MouseLeftButtonUp="circulito_MouseLeftButtonUp"
                 MouseMove="circulito_MouseMove"
                 />
    </Canvas>
</Window>

请注意 MainWindow.xaml Window 元素中,您还需要处理 MouseMove 事件...

 MouseMove="circulito_MouseMove"

我认为在 MouseMove 中你应该使用鼠标在 canvas 中的位置。因此给它起个名字

<Canvas x:Name="canvas">

然后你可以设置椭圆的位置

public void circulito_MouseMove(object sender, MouseEventArgs e)
{
    if (Mouse.LeftButton == MouseButtonState.Pressed) {
        var coorPutin = e.GetPosition(canvas);
        Canvas.SetLeft(circulito, coorPutin.X - coor.X);
        Canvas.SetTop(circulito, coorPutin.Y - coor.Y);
    }
}

此外,您必须从 MouseDown 中减去您得到的初始位置,因为您要将椭圆的 top/left 位置设置在鼠标位置的上方和左侧以保持鼠标光标在椭圆中的相对位置。

如果未初始化,

Canvas.GetLeft(this); 将 return NaN(不是数字)。因此最好使用

public void circulito_MouseDown(object sender, MouseButtonEventArgs e)
{
    coor = e.GetPosition(circulito);
}

非常感谢您回答我的Codexer。 xaml 代码保持不变。 最后把c#代码改成下面的就好了

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        Point coor;

        private void circulito_MouseDown(object sender, MouseButtonEventArgs e)
        {
            coor = e.GetPosition(circulito);
        }

        private void circulito_MouseMove(object sender, MouseEventArgs e)
        {
            if (Mouse.LeftButton == MouseButtonState.Pressed)
            {
                circulito.SetValue(Canvas.LeftProperty, e.GetPosition(this).X - coor.X);
                circulito.SetValue(Canvas.TopProperty, e.GetPosition(this).Y - coor.Y);
            }
        }
    }