即使光标位于画布外,也会调用MouseMove事件。 `Border`around画布不起作用

时间:2015-06-08 09:13:42

标签: c# wpf mousemove

对未来情况的简短描述:

只要鼠标在我的画布上移动,我就想在画布上显示一个椭圆。椭圆应该坚持鼠标移动,直到用户按下鼠标左键。当用户点击鼠标左键时,程序应该将椭圆放在画布上。

因此我使用了以下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();            
            }


         }
    }

问题是,只要鼠标离开画布,椭圆仍然会粘在鼠标上,甚至可以将椭圆放在画布外。

首先,我使用代码(代码来自stijn:C# - WPF - Mousemove event on canvas will overload the mouse events so click event is not fired),而xaml代码中的画布周围没有Border。然后我读到它可能有助于在画布(MouseMove event is called even when cursor is outside of canvas)周围放置Border并将其实现为xaml代码,如您所见。不幸的是,它没有帮助。

有人可以帮我解决问题吗?我非常感谢代码解决方案,因为我是c#的初学者。

1 个答案:

答案 0 :(得分:3)

您希望在控件中实现Adorners。请阅读它们,因为它们很容易在wpf中轻松执行这些操作。

然而,要解决您的问题。您应该在代码中实施MouseEnterMouseLeave个事件。在MouseEnter上添加形状,然后移除MouseLeaveMouseDown上的形状。因此,当Mouse ReEnters画布时,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();
            }

        }
    }