【问题标题】:Shaking in dragging object拖动物体时抖动
【发布时间】:2021-03-01 16:09:08
【问题描述】:

我是 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);
            }
        }

【问题讨论】:

  • 请包含问题中的所有相关代码,以便我们进行复制。您没有circulito_MouseUp 的例程,这应该会生成CS1061 错误。
  • 抱歉,我忘了删除“MouseUp = circulito_MouseUp”

标签: c# wpf drag-and-drop mousemove mousedown


【解决方案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"

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我认为在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);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多