拖动对象时抖动

发布时间:2021-03-01 16:09

我是 C# 的新手。 我一直在使用 MouseDown 和 MouseMove 在 C# (wpf) 中进行测试。尝试创建一个简单的椭圆,可以在画布内通过单击和移动鼠标来拖动它。 一切都很好,直到我运行代码,我看到当我拖动椭圆时它会抖动。 我知道对某些人来说这不是问题,但对我来说却是。 接下来是我使用的 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);
            }
        }

回答1
<块引用>

一切都很好,直到我运行代码,我看到当我拖动椭圆时它会抖动

这是因为您的 circulito_MouseMove 例程。您不需要检查按钮是否关闭,也不需要检查您是否正在尝试设置画布,这行不通,您需要设置元素(椭圆)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"

enter image description here

回答2

我认为在 MouseMove 中您应该使用鼠标在画布中的位置。因此给它一个名字

<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 中减去您得到的初始位置,因为您想将椭圆的上/左位置设置在鼠标位置的上方和左侧,以保持鼠标位置的相对位置鼠标光标位于椭圆中。

Canvas.GetLeft(this); 如果尚未初始化,将返回 NaN(不是数字)。因此最好使用

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

非常感谢 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);
            }
        }
    }

mousedown 相关推荐