canvas教程

canvas上的Mousemove事件将重载鼠标事件,因此点击事件不会触发

字号+ 作者:H5之家 来源:H5之家 2017-07-29 12:04 我要评论( )

C# - WPF - canvas上的Mousemove事件将重载鼠标事件,因此点击事件不会触发(C# - WPF - Mousemove event on canvas will overload the mouse events so click 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" 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 ); } } }

本文地址:IT屋 » C# - WPF - Mousemove event on canvas will overload the mouse events so click event is not fired

问 题

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



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



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



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



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



这里是不是



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



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



EDIT >

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



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



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



 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 用Javascript和canvas实现的涂鸦板,似乎不支持IE8及以下浏览器

    用Javascript和canvas实现的涂鸦板,似乎不支持IE8及以下浏览器

    2017-07-29 13:00

  • 当屏幕调整大小时调整画布大小

    当屏幕调整大小时调整画布大小

    2017-07-29 08:00

  • Canvas 绘制粒子动画背景

    Canvas 绘制粒子动画背景

    2017-07-27 12:05

  • HTML5 Canvas 爆炸动画特效

    HTML5 Canvas 爆炸动画特效

    2017-07-27 11:10

网友点评
i