Question

I'm trying to move a dynamically drawn rectangle inside the canvas. I’m able to draw the rectangle dynamically with in the canvas and while trying to move the rectangle inside the canvas I’m facing problem

XAML :

   <Grid x:Name="Gridimage1" Margin="0,0,411,100">
      <Image Name="image1" HorizontalAlignment="Left" Stretch="Fill" VerticalAlignment="Top"></Image>
        <Canvas x:Name="BackPanel" Margin="20,67,0,0" Height="317" Width="331">
           <Rectangle x:Name="selectionRectangle" Stroke="LightBlue" Fill="#220000FF"/>
        </Canvas>
   </Grid>

C# :

After drawing the rectangle dynamically I'm adding the below mouse events.

selectionRectangle.MouseLeftButtonDown += new MouseButtonEventHandler(Rect1_MouseDown);
selectionRectangle.MouseMove += new MouseEventHandler(Rectangle_MouseMove_1);
selectionRectangle.MouseUp += new MouseButtonEventHandler(Rect1_MouseUp); 
     # region "rectangle move"
    private bool drag = false;
    private Point startPt;
    private int wid;
    private int hei;
    private Point lastLoc;
    private double CanvasLeft, CanvasTop;
    private void Rect1_MouseDown(object sender, MouseButtonEventArgs e)
    {
        drag = true;
        Cursor = Cursors.Hand;
        startPt = e.GetPosition(BackPanel);
        wid = (int)selectionRectangle.Width;
        hei = (int)selectionRectangle.Height;
        lastLoc = new Point(Canvas.GetLeft(selectionRectangle), Canvas.GetTop(selectionRectangle));
       Mouse.Capture((IInputElement)sender);
    }

    private void Rectangle_MouseMove_1(object sender, MouseEventArgs e)
    {
        try
        {
            if (drag)
            {
                    var newX = (startPt.X + (e.GetPosition(BackPanel).X - startPt.X));
                    var newY = (startPt.Y + (e.GetPosition(BackPanel).Y - startPt.Y));
                    Point offset = new Point((startPt.X - lastLoc.X), (startPt.Y - lastLoc.Y));
                    CanvasTop = newY - offset.Y;
                    CanvasLeft = newX - offset.X;
                    selectionRectangle.SetValue(Canvas.TopProperty, CanvasTop);
                    selectionRectangle.SetValue(Canvas.LeftProperty, CanvasLeft);               

            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);    
        }

    }
    private void Rect1_MouseUp(object sender, MouseButtonEventArgs e)
    {
        drag = false;
        Cursor = Cursors.Arrow;
        Mouse.Capture(null);
    }
    #endregion

Problem: I'm able to move the rectangle all over the window. I want only to move the rectangle inside the canvas margin.

enter image description here

I'm able to move the rectangle outside the canvas

enter image description here

Was it helpful?

Solution

You should be able to get the Bounds of your selectionRectangle and see if they exceed the Width and/or Height of your canvas before committing the drag operation.

selectionRectangle.MouseMove += new MouseEventHandler(Rectangle_MouseMove_1);

private bool drag = false;
private Point startPt;
private int wid;
private int hei;
private Point lastLoc;
private double CanvasLeft, CanvasTop;

private void Rectangle_MouseMove_1(object sender, MouseEventArgs e)
{
    try
    {
        if (drag)
        {
                var newX = (startPt.X + (e.GetPosition(BackPanel).X - startPt.X));
                var newY = (startPt.Y + (e.GetPosition(BackPanel).Y - startPt.Y));
                Point offset = new Point((startPt.X - lastLoc.X), (startPt.Y - lastLoc.Y));
                CanvasTop = newY - offset.Y;
                CanvasLeft = newX - offset.X;

                // check if the drag will pull the rectangle outside of it's host canvas before performing
                // TODO: protect against lower limits too...
               if ((CanvasTop + selectionRectangle.Height > BackPanel.Height) || (CanvasLeft + selectionRectangle.Width > BackPanel.Width) || CanvasTop < 0 || CanvasLeft < 0)
                    {
                        return;
                    }
                selectionRectangle.SetValue(Canvas.TopProperty, CanvasTop);
                selectionRectangle.SetValue(Canvas.LeftProperty, CanvasLeft);               

        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);    
    }

}

OTHER TIPS

if ((CanvasTop + selectionRectangle.ActualHeight > BackPanel.ActualHeight))
{
    CanvasTop = BackPanel.ActualHeight - selectionRectangle.ActualHeight;
}

if (CanvasLeft + selectionRectangle.ActualWidth > BackPanel.ActualWidth)
{
    CanvasLeft = BackPanel.ActualWidth - selectionRectangle.ActualWidth;
}

if (CanvasTop < 0)
{
    CanvasTop = 0;
}

if (CanvasLeft < 0)
{
    CanvasLeft = 0;
} 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top