C# - WPF - canvas上的Mousemove事件将重载鼠标事件,因此点击事件不会触发 [英] C# - WPF - Mousemove event on canvas will overload the mouse events so click event is not fired

查看:3869
本文介绍了C# - WPF - canvas上的Mousemove事件将重载鼠标事件,因此点击事件不会触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用形状和画布,我想做一个像地图编辑器。当鼠标移动到画布上时,我在每次移动时将实际选择的对象绘制到鼠标位置的画布上,所以使用程序的用户可以看到如果对象放置在那里,它将是什么样子。



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



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



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



这里是当鼠标移动事件使用



这里是不是



我认为这是因为move事件oveload事件处理,没有资源来运行点击事件。



如何一起使用这两个活动?



EDIT >

我建议附加一些代码到示例中。



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



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



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

  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 c $ c>方法如下:

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

foreach(mapEditorModel.MapObjects中的MapElementContainer项)
{
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();
}

EDIT 2



如果我注释鼠标移动函数中的所有代码,那么我仍然不能在画布上第一次点击任何元素,所以也许是设计?

解决方案

这里是一个最小的代码示例,它可以正常工作,没有你提到的问题:可以点击。我建议你检查与你的代码的差异找到罪魁祸首 - 一个,我不连续调用updateCanvas或类似,因为这是不需要的。



xaml: / p>

 < Window x:Class =WpfApplication1.MainWindow
xmlns =http://schemas.microsoft。 com / winfx / 2006 / xaml / presentation
xmlns:x =http://schemas.microsoft.com/winfx/2006/xaml
Title =MainWindowSizeToContent =WidthAndHeight ;
< Canvas x:Name =canvasBackground =AntiqueWhiteWidth =1024Height =768
MouseMove =Canvas_MouseMoveMouseDown =Canvas_MouseDown/&
< / Window>

xaml.cs:

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

命名空间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>形状;
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);
}
}
}


I use Shapes and Canvas, I want to make something like a mapeditor. When the mouse move over the canvas I draw the actually selected object to the canvas at the mouse position on every move, so who use the program can see how it will look like if the object is placed there.

And on mouse click I add the current object/position to a list, which contains the placed elements which need to be drawn on the canvas in every update.

The problem is if the mouse move handler is active (binded to canvas) then the click event is not fired alway, I need to click continuously For about ten clicks to place the element. If the mouse move event is not binded then the click works perfectly.

I made a GIF to demonstrate my problem.

Here is when the mouse move event is used

and here is when not

I think it's because the move event oveload the event handling, and there is no resource to run the click event.

How I could use the two event together?

EDIT

As advised, I attach some code to the example.

I have a model for the canvas named mapEditorModel. The property which is important to us is the mapEditorModel.MapObjects which is a list containing the elements need to be drawed to the canvas.

The list contains a wrapper object, its contains a lot of information about the elment, which is important to us is that it contains the prebuild shape for draw.

I have a function which is draw the elments on the canvas:

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

And I have an updateCanvas() method like this:

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

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

And the two event method is:

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();
    }

EDIT 2

If I comment all the code in the mouse move function, then I still can't place any element on the canvas at the first click, so maybe is it by design?

解决方案

Here's a minimal code sample which works properly and does not have the problem you mention: it can add shapes as fast as I can click. I suggest you inspect the differences with your code to find the culprit - for one, I don't continuously call updateCanvas or similar as this is not needed.

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

这篇关于C# - WPF - canvas上的Mousemove事件将重载鼠标事件,因此点击事件不会触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆