【问题标题】:Make Object Follow Mouse On MouseDown and "Stick" On MouseUp使对象在 MouseDown 上跟随鼠标并在 MouseUp 上“坚持”
【发布时间】:2011-04-14 06:07:20
【问题描述】:

我正在使用 WPF 和 VB.net 的项目。我想直观地模拟“拖动”一个对象(尽管出于目的我不想使用标准拖放)。

基本上,我有一个标签对象,在它的 MouseDown 事件中,我希望它在 640x480 纯尺寸网格内跟随鼠标光标(但不在它之外!)。请注意,此网格位于全屏窗口的中心。同样,对象不应跟随网格外的鼠标(我在这里猜测“ClipToBounds = True”)

然后,在标签的 MouseUp 事件中,我希望它保持在当前位置或返回其原始位置,这由另一个对象的 MouseEnter 属性设置的布尔变量的值决定。

注意,如果使用起来更容易,我可以轻松地将网格更改为画布。我猜这将是可取的。

所以,在冗长的解释之后,这是我的问题(双重):

  1. 如何使对象(标签)在网格/画布内跟随鼠标光标,但不在其外部?这需要在标签的 MouseDown 事件上发生。

  2. 如何使对象“粘”在其当前位置? (由此,我大概可以自己弄清楚如何让它回到原来的位置。:D)

我赞成任何可以帮助我最有效地实现这一目标的人!非常感谢大家。

【问题讨论】:

    标签: wpf vb.net cursor-position onmousedown onmouseup


    【解决方案1】:

    这样的事情怎么样:

    XAML:

    <Canvas x:Name="canv" ToolTip="tt one" Width="400" Height="400" Background="Blue">
        <Rectangle x:Name="rec" Fill="Red" Height="50" Width="50" MouseDown="Rectangle_MouseDown" MouseMove="Rectangle_MouseMove" MouseUp="Rectangle_MouseUp" />
    </Canvas>
    

    代码隐藏:

        private bool isDragging;
        private void Rectangle_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            rec.CaptureMouse();
            isDragging = true;
    
        }
    
        private void Rectangle_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (isDragging)
            {
                Point canvPosToWindow = canv.TransformToAncestor(this).Transform(new Point(0, 0));
    
                Rectangle r = sender as Rectangle;
                var upperlimit = canvPosToWindow.Y + (r.Height / 2);
                var lowerlimit = canvPosToWindow.Y + canv.ActualHeight - (r.Height / 2);
    
                var leftlimit = canvPosToWindow.X + (r.Width / 2);
                var rightlimit = canvPosToWindow.X + canv.ActualWidth - (r.Width / 2);
    
    
                var absmouseXpos = e.GetPosition(this).X;
                var absmouseYpos = e.GetPosition(this).Y;
    
                if ((absmouseXpos > leftlimit && absmouseXpos < rightlimit)
                    && (absmouseYpos > upperlimit && absmouseYpos < lowerlimit))
                {
                    Canvas.SetLeft(r, e.GetPosition(canv).X - (r.Width / 2));
                    Canvas.SetTop(r, e.GetPosition(canv).Y - (r.Height / 2));
                }
            }
        }
    
        private void Rectangle_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            rec.ReleaseMouseCapture();
            isDragging = false;
        }
    

    这段代码可以增强,但我想你明白了;)

    【讨论】:

    • 太棒了!!!!!!!只是给任何使用这个的人一个注释......确保你在画布上拖动的任何对象都没有设置边距属性!否则,您将有相当大的偏移量。 :3
    • 设置边距没有问题,我想画布和移动对象都不是,你只需要在计算你的colision值时考虑它们;)
    • 如果在将网格更改为画布之前将它们用于在网格中定位,那么这些边距也会在拖动时大大偏离鼠标悬停在对象上的点。据我所知,定位边距值在画布上没有任何作用,因此最好将它们设置为“0”。
    【解决方案2】:

    基于@Bruno,这是我的解决方案:

    double maxX;
    double maxY;
    
    private void OnRectMouseDown(object sender, MouseButtonEventArgs e)
    {
        maxX = canv.ActualWidth - rect.Width;
        maxY = canv.ActualHeight - rect.Height;
    
        rect.CaptureMouse();
        rect.MouseMove += OnRectMouseMove;
        rect.MouseUp += OnRectMouseUp;
    }
    
    private void OnRectMouseMove(object sender, MouseEventArgs e)
    {
        var pos = e.GetPosition(canv);
        var newX = pos.X - (rect.Width / 2);
        var newY = pos.Y - (rect.Height / 2);
    
        if (newX < 0) newX = 0;
        if (newX > maxX) newX = maxX;
    
        if (newY < 0) newY = 0;
        if (newY > maxY) newY = maxY;
    
        rect.SetValue(Canvas.LeftProperty, newX);
        rect.SetValue(Canvas.TopProperty, newY);
    
        xVal.Content = (newX / maxX).ToString("F3");
        yVal.Content = (newY / maxY).ToString("F3");
    }
    
    private void OnRectMouseUp(object sender, MouseButtonEventArgs e)
    {
        rect.ReleaseMouseCapture();
        rect.MouseMove -= OnRectMouseMove;
        rect.MouseUp -= OnRectMouseUp;
    }
    

    【讨论】:

      【解决方案3】:

      试试这个:

      private void Form1_MouseClick(object sender, MouseEventArgs e)
      {
          (name).Location = new Point(e.X,e.Y);
      }
      

      这样就可以了,所以如果你点击对象就会出现在那里

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-05
        • 1970-01-01
        • 2016-07-22
        • 2023-03-07
        • 1970-01-01
        • 2016-07-02
        • 1970-01-01
        相关资源
        最近更新 更多