Domanda

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.

È stato utile?

Soluzione

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top