画布上的C#-WPF-Mousemove事件将重载鼠标事件,因此不会触发click事件
我使用形状和画布,我想做一些像地图编辑器的东西。当鼠标在画布上移动时,每次移动时,我都会在鼠标位置将实际选定的对象绘制到画布上,这样使用该程序的人就可以看到如果将对象放置在画布上,它会是什么样子 单击鼠标,我将当前对象/位置添加到一个列表中,其中包含在每次更新时需要在画布上绘制的放置元素 问题是,如果鼠标移动处理程序处于活动状态(绑定到画布),则不会一直触发单击事件,我需要连续单击大约十次以放置元素。如果鼠标移动事件未绑定,则单击可以正常工作 我做了一个GIF来演示我的问题 这里是使用鼠标移动事件的时间 这里是不在的时候 我认为这是因为move事件没有加载事件处理,并且没有资源运行click事件 我怎么能把这两件事结合起来呢 编辑 如前所述,我在示例中附加了一些代码 我有一个画布模型,名为画布上的C#-WPF-Mousemove事件将重载鼠标事件,因此不会触发click事件,c#,wpf,canvas,mouseevent,C#,Wpf,Canvas,Mouseevent,我使用形状和画布,我想做一些像地图编辑器的东西。当鼠标在画布上移动时,每次移动时,我都会在鼠标位置将实际选定的对象绘制到画布上,这样使用该程序的人就可以看到如果将对象放置在画布上,它会是什么样子 单击鼠标,我将当前对象/位置添加到一个列表中,其中包含在每次更新时需要在画布上绘制的放置元素 问题是,如果鼠标移动处理程序处于活动状态(绑定到画布),则不会一直触发单击事件,我需要连续单击大约十次以放置元素。如果鼠标移动事件未绑定,则单击可以正常工作 我做了一个GIF来演示我的问题 这里是使用鼠标移动事
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 );
}
}
}