当前位置: 首页 > 知识库问答 >
问题:

C#-WPF-画布上的Mousemove事件将重载鼠标事件,因此不会触发单击事件

陆飞捷
2023-03-14

我使用形状和画布,我想做一些像地图编辑器的东西。当鼠标在画布上移动时,我会在每次移动时将实际选定的对象绘制到画布上的鼠标位置,以便使用该程序的用户可以看到该对象放置在画布上时的外观。

单击鼠标,我将当前对象/位置添加到列表中,其中包含每次更新都需要在画布上绘制的放置元素。

问题是,如果鼠标移动处理程序处于活动状态(绑定到画布),那么click事件不会一直触发,我需要连续单击大约十次来放置元素。如果鼠标移动事件未绑定,则单击效果很好。

我做了一个GIF来演示我的问题。

我认为这是因为move事件没有加载事件处理,并且没有资源来运行click事件。

我怎么能同时使用这两个事件?

编辑

根据建议,我在示例中附加了一些代码。

我有一个名为mapEditorModel的画布模型。对我们来说很重要的属性是mapEditorModel。MapObject是一个包含需要绘制到画布的元素的列表。

列表包含一个包装对象,它包含了很多关于元素的信息,这对我们来说很重要,因为它包含了绘制的预构建形状。

我有一个功能是在画布上绘制元素:

private void DrawElementOnCanvas(MapElementContainer item)
    {
        Rectangle shape = item.Shape;

        CanvasElement.Children.Add(shape);
        Canvas.SetLeft(shape, item.Position.X);
        Canvas.SetTop(shape, item.Position.Y);    
    }

我有一个updateCanvas()方法,如下所示:

private void updateCanvas()
    {
        CanvasElement.Children.RemoveRange(0, CanvasElement.Children.Count);

        foreach (MapElementContainer item in mapEditorModel.MapObjects)
        {
            DrawElementOnCanvas(item);   
        }
        //CollisionDetection();
    }

两个事件方法是:

private void CanvasElement_MouseMove(object sender, MouseEventArgs e)
    {
        updateCanvas();

        MapElementContainer mapObject = new MapElementContainer();

        mapObject.Position = e.GetPosition((Canvas)sender);
        mapObject.MapElement = new ContainerMapObject();
        mapObject.CurrentRotateDegree = mapEditorModel.CurrentRotateDegree;
        mapObject.Shape = BuildShape(mapObject);

        DrawElementOnCanvas(mapObject);   
    }

private void CanvasElement_MouseDown(object sender, MouseButtonEventArgs e)
    {
        MapElementContainer mapObject = new MapElementContainer();

        mapObject.Position = e.GetPosition((Canvas)sender);
        mapObject.MapElement = new ContainerMapObject();
        mapObject.CurrentRotateDegree = mapEditorModel.CurrentRotateDegree;
        mapObject.Shape = BuildShape(mapObject);

        mapEditorModel.MapObjects.Add(mapObject);

        updateCanvas();
    }

编辑2

如果我注释鼠标移动函数中的所有代码,那么我仍然无法在第一次单击时将任何元素放置在画布上,所以可能是设计好的?

共有2个答案

邢博文
2023-03-14

也许MouseDown事件是在MapElementContainer类中处理的,并且从未到达CanvasElement?在第二个视频中,您总是单击一个空白区域。在第一个视频中,鼠标下始终有MapElementContainer。

钮誉
2023-03-14

这里有一个最小的代码示例,它工作正常,没有您提到的问题:它可以以我可以单击的速度添加形状。我建议您检查代码的差异,以找到罪魁祸首——首先,我不连续调用updateCanvas或类似的函数,因为这是不需要的。

xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight">
  <Canvas x:Name="canvas" Background="AntiqueWhite" Width="1024" Height="768"
          MouseMove="Canvas_MouseMove" MouseDown="Canvas_MouseDown" />
</Window>

xaml.cs:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfApplication1
{
  public class Item
  {
    private readonly Rectangle shape;

    public Item( Canvas canvas )
    {
      shape = new Rectangle { Width = 50, Height = 50, Fill = Brushes.Black };
      canvas.Children.Add( shape );
      SetPosition( 0.0, 0.0 );
    }

    public void SetPosition( double x, double y )
    {
      Canvas.SetLeft( shape, x );
      Canvas.SetTop( shape, y );
    }
  }

  public partial class MainWindow : Window
  {
    private readonly IList<Item> shapes;
    private Item currentMovingShape;

    public MainWindow()
    {
      InitializeComponent();
      shapes = new List<Item>();
      InitMovingShape();
    }

    private void InitMovingShape()
    {
      currentMovingShape = new Item( canvas );
    }

    private void SetMovingShapePosition( MouseEventArgs e )
    {
      var pos = e.GetPosition( canvas );
      currentMovingShape.SetPosition( pos.X, pos.Y );
    }

    private void Canvas_MouseMove( object sender, MouseEventArgs e )
    {
      SetMovingShapePosition( e );
    }

    private void Canvas_MouseDown( object sender, MouseButtonEventArgs e )
    {
      shapes.Add( currentMovingShape );
      InitMovingShape();
      SetMovingShapePosition( e );
    }
  }
}
 类似资料:
  • 我在画布上处理鼠标事件时遇到问题。我想用鼠标来绘制它,我已经想出了这些事件处理程序,但当我开始绘制时,它们什么都不做。 你能帮我告诉我遗漏了什么或者如何重写它以便它开始工作吗?

  • 本文向大家介绍javascript触发模拟鼠标点击事件,包括了javascript触发模拟鼠标点击事件的使用技巧和注意事项,需要的朋友参考一下 事件触发器就是用来触发某个元素下的某个事件,IE下fireEvent方法,高级浏览器(chrome,firefox等)有dispatchEvent方法。 一般我们在元素上绑定事件后,是靠用户在这些元素上的鼠标行为来捕获或者触发事件的,或者自带的浏览器行为事

  • 我想在点击某个div(“.checker”)后触发点击输入事件。换句话说,点击'.checker'将模拟点击复选框上的点击事件,远程检查它。 我写的代码可以工作,但click只有在第二次单击后才触发,第一次单击失败时才触发。这种情况甚至不会发生在'.checker'上,也会发生在checkbox上。 下面的所有HTML都包装在jquery折叠菜单中。单击“H3”后,“.sub-tree-wrap”

  • 问题内容: 我正在使用与鼠标移动事件一起操作的YUI滑块。我想让它响应touchmove事件(iPhone和Android)。发生touchmove事件时如何产生鼠标移动事件?我希望仅在顶部添加一些脚本,即可将touchmove事件映射到鼠标移动事件,而无需使用滑块进行任何更改。 问题答案: 我确定这是您想要的: 我已经捕获了触摸事件,然后手动触发了自己的鼠标事件以进行匹配。尽管该代码并不是特别通

  • 问题内容: 在我的三个按钮上,鼠标=中键单击和=右键单击。 两键鼠标就是这种情况吗? 谢谢 问题答案: 为了避免任何歧义,请使用SwingUtilities中的实用程序方法:

  • 在本章中,我们将详细介绍鼠标事件及其属性。 请注意:此类事件不仅可能来自于“鼠标设备”,还可能来自于对此类操作进行了模拟以实现兼容性的其他设备,例如手机和平板电脑。 鼠标事件类型 我们已经见过了其中一些事件: mousedown/mouseup 在元素上点击/释放鼠标按钮。 mouseover/mouseout 鼠标指针从一个元素上移入/移出。 mousemove 鼠标在元素上的每个移动都会触发此