Moving the dynamically drawn rectangle inside the canvas using MouseMove event

19,164

Solution 1

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);    
    }

}

Solution 2

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;
} 
Share:
19,164

Related videos on Youtube

Jay
Author by

Jay

Updated on June 04, 2022

Comments

  • Jay
    Jay almost 2 years

    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

  • Jay
    Jay almost 10 years
    working great but few changes I'm making in your answer added --> (CanvasTop < 0 || CanvasLeft < 0).
  • Chris Badman
    Chris Badman almost 10 years
    Great! There'll probably be other things you'll have to protect against as you play around with it, but you get the general idea of how to.