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

画布上的C#-WPF-Mousemove事件将重载鼠标事件,因此不会触发click事件,c#,wpf,canvas,mouseevent,C#,Wpf,Canvas,Mouseevent,我使用形状和画布,我想做一些像地图编辑器的东西。当鼠标在画布上移动时,每次移动时,我都会在鼠标位置将实际选定的对象绘制到画布上,这样使用该程序的人就可以看到如果将对象放置在画布上,它会是什么样子 单击鼠标,我将当前对象/位置添加到一个列表中,其中包含在每次更新时需要在画布上绘制的放置元素 问题是,如果鼠标移动处理程序处于活动状态(绑定到画布),则不会一直触发单击事件,我需要连续单击大约十次以放置元素。如果鼠标移动事件未绑定,则单击可以正常工作 我做了一个GIF来演示我的问题 这里是使用鼠标移动事

我使用形状和画布,我想做一些像地图编辑器的东西。当鼠标在画布上移动时,每次移动时,我都会在鼠标位置将实际选定的对象绘制到画布上,这样使用该程序的人就可以看到如果将对象放置在画布上,它会是什么样子

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

问题是,如果鼠标移动处理程序处于活动状态(绑定到画布),则不会一直触发单击事件,我需要连续单击大约十次以放置元素。如果鼠标移动事件未绑定,则单击可以正常工作

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

这里是使用鼠标移动事件的时间

这里是不在的时候

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

我怎么能把这两件事结合起来呢

编辑

如前所述,我在示例中附加了一些代码

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

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

我有一个在画布上绘制元素的函数:

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


如果我对鼠标移动功能中的所有代码进行注释,那么我仍然无法在第一次单击时将任何元素放置在画布上,那么这可能是出于设计

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

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

xaml:


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 );
    }
  }
}
使用System.Collections.Generic;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Shapes;
命名空间WpfApplication1
{
公共类项目
{
私有只读矩形形状;
公共物品(帆布)
{
形状=新矩形{宽度=50,高度=50,填充=画笔.Black};
canvas.Children.Add(shape);
设定位置(0.0,0.0);
}
公共无效设置位置(双x,双y)
{
Canvas.SetLeft(形状,x);
画布。机顶盒(形状,y);
}
}
公共部分类主窗口:窗口
{
私有只读IList形状;
私有项目当前移动形状;
公共主窗口()
{
初始化组件();
形状=新列表();
InitMovingShape();
}
私有void InitMovingShape()
{
currentMovingShape=新项目(画布);
}
专用无效设置移动形状位置(MouseEventArgs e)
{
var pos=e.GetPosition(画布);
当前移动形状设置位置(位置X、位置Y);
}
私有void Canvas_MouseMove(对象发送方,MouseEventArgs e)
{
设置移动形状位置(e);
}
私有void Canvas_MouseDown(对象发送器,MouseButtonEventArgs e)
{
形状。添加(当前移动形状);
InitMovingShape();
设置移动形状位置(e);
}
}
}

我喜欢你的GIF,但请为你的移动事件显示一些代码,因为问题可能出在你的代码中,而不仅仅是你绑定到事件的事实。我按照你的建议编辑了答案。我不熟悉在画布上绘制,但真的需要在移动事件中不断删除和添加所有项目吗?你不能更新一下职位吗?是的,这是一个消耗资源的解决方案,这可能是问题的根源吗?开始时它将是第一个,但当鼠标离开画布时需要将其移除,之后它将被放置在画布的末尾,但我如何在移动时知道最后一个是放置的(不应被覆盖)还是占位符?所以管理它并不容易,因为我不知道它在列表中的位置,所以很难决定何时需要覆盖列表中的一个或放置一个新的。也许完全单独处理会使技巧变得复杂。MapElementContainer不是作为GUI元素存在的,在鼠标下是我的画布,它实际上在那里的位置绘制了一个元素。或者从画布上单独处理形状?无论如何,它是画布的一个子部分,因此冒泡事件到达画布。谢谢,它工作得很好,问题在于在鼠标移动处理程序的开始调用
updateCanvas()
方法。
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 );
    }
  }
}