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

时间:2014-11-22 09:16:11

标签: c# wpf canvas mouseevent

我使用Shapes和Canvas,我想制作像mapeditor这样的东西。当鼠标在画布上移动时,我会在每次移动时将实际选择的对象绘制到鼠标位置的画布上,因此使用该程序的人可以看到如果将对象放在那里它会是什么样子。

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

问题是如果鼠标移动处理程序处于活动状态(绑定到画布),则单击事件不会被触发,我需要连续单击以进行大约十次单击以放置元素。如果鼠标移动事件没有绑定,则点击工作完美。

我做了一个GIF来证明我的问题。

以下是使用鼠标移动事件的时间

,这时不是

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

我如何一起使用这两个事件?

修改

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

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

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

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

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 个答案:

答案 0 :(得分:2)

这是一个最小的代码示例,它可以正常工作,并且没有您提到的问题:它可以尽可能快地添加形状。我建议你检查你的代码的差异,找出罪魁祸首 - 对于一个,我不会不断调用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 );
    }
  }
}

答案 1 :(得分:0)

也许MouseDown事件在MapElementContainer类中处理,永远不会到达CanvasElement?在第二个视频中,您总是点击一个空白区域。在您的第一个视频中,鼠标下始终存在MapElementContainer。