即使光标在 canvas 之外,也会调用 MouseMove 事件。 canvas 周围的“边框”无效
MouseMove event is called even when cursor is outside of canvas. `Border`around canvas did not work
未来情况的简短描述:
只要鼠标移到我的 canvas 上,我就想在 canvas 上显示一个椭圆。在用户点击鼠标左键之前,椭圆应该会一直跟随鼠标移动。当用户点击鼠标左键时,程序应将椭圆放置在 canvas.
上
因此我使用了以下 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" Height="700" Width="1200">
<Grid>
<Border ClipToBounds="true">
<Canvas x:Name="canvasss" Background="AntiqueWhite" Width="524" Height="368" MouseMove="Canvasss_MouseMove" MouseDown="Canvasss_MouseDown">
</Canvas>
</Border>
</Grid>
C# 代码:
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 Ellipse shape;
public Item(Canvas canvas)
{
shape = new Ellipse { 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(canvasss);
}
private void SetMovingShapePosition(MouseEventArgs e)
{
var pos = e.GetPosition(canvasss);
currentMovingShape.SetPosition(pos.X - 25, pos.Y - 25);
}
private void Canvasss_MouseMove(object sender, MouseEventArgs e)
{
var pos = e.GetPosition(canvasss);
currentMovingShape.SetPosition(pos.X - 25, pos.Y - 25);
}
private void Canvasss_MouseDown(object sender, MouseButtonEventArgs e)
{
shapes.Add(currentMovingShape);
InitMovingShape();
}
}
}
问题是,一旦鼠标离开canvas,椭圆仍然粘在鼠标上,甚至可以将椭圆放在canvas之外。
首先我使用了代码(代码来自stijn:C# - WPF - Mousemove event on canvas will overload the mouse events so click event is not fired) without the Border
around the canvas in the xaml code. Then I read it might help to place a Border
arround the canvas (MouseMove event is called even when cursor is outside of canvas)并将其实现为xaml代码,如您所见。不幸的是,它没有帮助。
有人可以帮我解决吗?代码解决方案将不胜感激,因为我是 c# 的初学者。
您似乎想在您的控件中实现 Adorners。请务必阅读它们,因为它们会派上用场,可以在 wpf 中轻松执行此类操作。
但是,要解决您的问题。您应该在代码中实施 MouseEnter
和 MouseLeave
事件。添加 MouseEnter
上的形状并删除 MouseLeave
或 MouseDown
上的形状。因此,当鼠标重新进入 canvas 时,MouseEnter 逻辑将启动并添加形状,而您的 MouseMove
逻辑将使用鼠标移动形状。希望我在这里说清楚。如果您仍在为代码苦苦挣扎,请告诉我。
编辑
xaml
<Grid Background="Transparent">
<Canvas x:Name="canvasss" Background="AntiqueWhite" Width="300" Height="300" MouseEnter="canvasss_MouseEnter" MouseLeave="canvasss_MouseLeave" MouseMove="Canvasss_MouseMove" MouseDown="Canvasss_MouseDown" Margin="50" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
代码
public partial class MainWindow : Window
{
private readonly IList<Ellipse> shapes;
private Ellipse currentMovingShape;
public MainWindow()
{
InitializeComponent();
shapes = new List<Ellipse>();
}
private void canvasss_MouseEnter(object sender, MouseEventArgs e)
{
AddEllipse();
}
private void AddEllipse()
{
currentMovingShape = new Ellipse { Width = 50, Height = 50, Fill = Brushes.Black };
currentMovingShape.IsHitTestVisible = false;
canvasss.Children.Add(currentMovingShape);
Canvas.SetLeft(currentMovingShape, Mouse.GetPosition(canvasss).X - 25);
Canvas.SetTop(currentMovingShape, Mouse.GetPosition(canvasss).Y - 25);
}
private void canvasss_MouseLeave(object sender, MouseEventArgs e)
{
if (currentMovingShape != null)
{
canvasss.Children.Remove(currentMovingShape);
currentMovingShape = null;
}
}
private void Canvasss_MouseMove(object sender, MouseEventArgs e)
{
Canvas.SetLeft(currentMovingShape, e.GetPosition(canvasss).X - 25);
Canvas.SetTop(currentMovingShape, e.GetPosition(canvasss).Y - 25);
}
private void Canvasss_MouseDown(object sender, MouseButtonEventArgs e)
{
if (currentMovingShape != null)
{
currentMovingShape.IsHitTestVisible = true;
shapes.Add(currentMovingShape);
AddEllipse();
}
}
}
未来情况的简短描述:
只要鼠标移到我的 canvas 上,我就想在 canvas 上显示一个椭圆。在用户点击鼠标左键之前,椭圆应该会一直跟随鼠标移动。当用户点击鼠标左键时,程序应将椭圆放置在 canvas.
上因此我使用了以下 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" Height="700" Width="1200">
<Grid>
<Border ClipToBounds="true">
<Canvas x:Name="canvasss" Background="AntiqueWhite" Width="524" Height="368" MouseMove="Canvasss_MouseMove" MouseDown="Canvasss_MouseDown">
</Canvas>
</Border>
</Grid>
C# 代码:
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 Ellipse shape;
public Item(Canvas canvas)
{
shape = new Ellipse { 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(canvasss);
}
private void SetMovingShapePosition(MouseEventArgs e)
{
var pos = e.GetPosition(canvasss);
currentMovingShape.SetPosition(pos.X - 25, pos.Y - 25);
}
private void Canvasss_MouseMove(object sender, MouseEventArgs e)
{
var pos = e.GetPosition(canvasss);
currentMovingShape.SetPosition(pos.X - 25, pos.Y - 25);
}
private void Canvasss_MouseDown(object sender, MouseButtonEventArgs e)
{
shapes.Add(currentMovingShape);
InitMovingShape();
}
}
}
问题是,一旦鼠标离开canvas,椭圆仍然粘在鼠标上,甚至可以将椭圆放在canvas之外。
首先我使用了代码(代码来自stijn:C# - WPF - Mousemove event on canvas will overload the mouse events so click event is not fired) without the Border
around the canvas in the xaml code. Then I read it might help to place a Border
arround the canvas (MouseMove event is called even when cursor is outside of canvas)并将其实现为xaml代码,如您所见。不幸的是,它没有帮助。
有人可以帮我解决吗?代码解决方案将不胜感激,因为我是 c# 的初学者。
您似乎想在您的控件中实现 Adorners。请务必阅读它们,因为它们会派上用场,可以在 wpf 中轻松执行此类操作。
但是,要解决您的问题。您应该在代码中实施 MouseEnter
和 MouseLeave
事件。添加 MouseEnter
上的形状并删除 MouseLeave
或 MouseDown
上的形状。因此,当鼠标重新进入 canvas 时,MouseEnter 逻辑将启动并添加形状,而您的 MouseMove
逻辑将使用鼠标移动形状。希望我在这里说清楚。如果您仍在为代码苦苦挣扎,请告诉我。
编辑
xaml
<Grid Background="Transparent">
<Canvas x:Name="canvasss" Background="AntiqueWhite" Width="300" Height="300" MouseEnter="canvasss_MouseEnter" MouseLeave="canvasss_MouseLeave" MouseMove="Canvasss_MouseMove" MouseDown="Canvasss_MouseDown" Margin="50" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
代码
public partial class MainWindow : Window
{
private readonly IList<Ellipse> shapes;
private Ellipse currentMovingShape;
public MainWindow()
{
InitializeComponent();
shapes = new List<Ellipse>();
}
private void canvasss_MouseEnter(object sender, MouseEventArgs e)
{
AddEllipse();
}
private void AddEllipse()
{
currentMovingShape = new Ellipse { Width = 50, Height = 50, Fill = Brushes.Black };
currentMovingShape.IsHitTestVisible = false;
canvasss.Children.Add(currentMovingShape);
Canvas.SetLeft(currentMovingShape, Mouse.GetPosition(canvasss).X - 25);
Canvas.SetTop(currentMovingShape, Mouse.GetPosition(canvasss).Y - 25);
}
private void canvasss_MouseLeave(object sender, MouseEventArgs e)
{
if (currentMovingShape != null)
{
canvasss.Children.Remove(currentMovingShape);
currentMovingShape = null;
}
}
private void Canvasss_MouseMove(object sender, MouseEventArgs e)
{
Canvas.SetLeft(currentMovingShape, e.GetPosition(canvasss).X - 25);
Canvas.SetTop(currentMovingShape, e.GetPosition(canvasss).Y - 25);
}
private void Canvasss_MouseDown(object sender, MouseButtonEventArgs e)
{
if (currentMovingShape != null)
{
currentMovingShape.IsHitTestVisible = true;
shapes.Add(currentMovingShape);
AddEllipse();
}
}
}