我使用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
如果我评论鼠标移动功能中的所有代码,那么我仍然无法在第一次点击时在画布上放置任何元素,所以也许它是设计的?
最佳答案 这是一个最小的代码示例,它可以正常工作并且没有您提到的问题:它可以尽可能快地添加形状.我建议你检查你的代码的差异,找到罪魁祸首 – 对于一个,我不会连续调用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 );
}
}
}