Question

I have a canvas surrounded by a border defined like so

XAML :

<Border x:Name="CanvasBorder" BorderThickness="1" BorderBrush="Black" 
        HorizontalAlignment="Left" VerticalAlignment="Top" Height="480"
        Width="541"  Margin="50,50,0,0">
   <Canvas x:Name="CanvaContainer" Background="Transparent"
           HorizontalAlignment="Left" Height="479" Margin="1,1,1,1" 
           VerticalAlignment="Top" Width="540"
           MouseMove="CanvaContainer_MouseMove"/>
</Border>

And this is the mouse event

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;

namespace testing
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private double[][] array;
        private Rectangle rectCurrent;
        private int xPrevious = -1, yPrevious = -1, xCurrent = 0, yCurrent = 0;

        public MainWindow()
        {
            InitializeComponent();

            XDocument doc = XDocument.Load("Akulivik_Clay_High_Shrub.Xml");
            array = doc.Root.Elements("Month").Select(month => month.Elements().Select(x => (double)x).ToArray()).ToArray();
        }

        private void CanvaContainer_MouseMove(object sender, MouseEventArgs e)
        {
            Position(Mouse.GetPosition(CanvaContainer).X, Mouse.GetPosition(CanvaContainer).Y, out xCurrent, out yCurrent);

            valueXY.Content = String.Format("Array[Y : {1}][X : {0}] : {2}", xCurrent, yCurrent, array[yCurrent][xCurrent >= array.GetLength(0) ? 12 : xCurrent].ToString());

            realX.Content = "X : " + e.GetPosition(CanvaContainer).X;
            realY.Content = "Y : " + e.GetPosition(CanvaContainer).Y;

            if (!(xCurrent == xPrevious) && !(yCurrent == yPrevious))
                {

                    rectCurrent = new Rectangle();
                    rectCurrent.Stroke = new SolidColorBrush(Colors.Black);
                    rectCurrent.StrokeThickness = 2;
                    rectCurrent.Width = 45;
                    rectCurrent.Height = 40;
                    Canvas.SetLeft(rectCurrent, 45 * (xCurrent - 1));
                    Canvas.SetTop(rectCurrent, 40 * yCurrent);
                    CanvaContainer.Children.Add(rectCurrent);
                }
            else if (xCurrent == xPrevious && yCurrent == yPrevious)
                {
                    Console.WriteLine("Nothing");
                    xPrevious = xCurrent;
                    yPrevious = yCurrent;
                }
            else
                {
                    CanvaContainer.Children.Remove(rectCurrent);
                    Console.WriteLine("Outside");
                }       
        }

        private void Position(double xPos, double yPos, out int xValue, out int yValue)
        {
            xValue = (int)Math.Truncate(xPos / (int)45) +1;
            yValue = (int)Math.Truncate(yPos / (int)40);
        }
    }
}

So the point is, when I draw a rectangle over the mouse, everythings is fine, but when I reach the border of the rectangle wich is on the border of the canva it create another rectangle since the event is raised because the rectangle is a child of the canva so I assume it's having the same event raised. The behaviours is shown below with picture.

Reaching the border : enter image description here

When reached : enter image description here

To be more clear, on the second picture, there should be no rectangle even if I reach the border. If you need more description just say it in comment.

Was it helpful?

Solution

Most of the code needed to compile and run your example is missing, if you provide a fully working example then you'll have a better chance of this question being answered. In the mean time try setting the border's SnapsToDevicePixels property to "True".

UPDATE: you've got a few problems going on here. Your Canvas is the wrong size and has a 1 pixel margin, your border isn't giving it enough space and you're assuming that the hit test means the cursor is within the canvas limits (default hittest behaviour in WPF is a hit along the right edge as well). Try changing your xaml to this:

<Border x:Name="CanvasBorder" BorderThickness="1" BorderBrush="Black"  HorizontalAlignment="Left" VerticalAlignment="Top" Margin="50,50,0,0" >
    <Canvas x:Name="CanvaContainer" Background="Transparent" Height="480" Width="540" MouseMove="CanvaContainer_MouseMove" />
</Border>

And the start of your mouse move handler to this:

private void CanvaContainer_MouseMove(object sender, MouseEventArgs e)
{
    var pt = Mouse.GetPosition(CanvaContainer);
    if ((pt.X >= CanvaContainer.ActualWidth) || (pt.Y >= CanvaContainer.ActualHeight))
        return;
    Position(pt.X, pt.Y, out xCurrent, out yCurrent);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top