2014-07-18 1 views
0

캔버스에 직사각형을 그린 WPF 응용 프로그램이 있습니다. 직사각형을 그릴 때 직사각형을 그리는 기능을 추가해야합니다 (예 : 첫 번째로 가정). 사각형 x 좌표는 236이고 두 번째 사각형 좌표는 235입니다.) 이미지에 표시된대로 두 번째 사각형 x 좌표를 236에 스냅해야합니다. enter image description here 거리 차이가 10 인 경우에만 스냅이 수행됩니다.그려진 사각형을 서로 맞 춥니 다.

나는 이것을 수행하기 위해 다음 코드를 작성했습니다.

private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) 
     {       
      startPos = e.GetPosition(Canvas); 
      System.Windows.Point curPosition = e.GetPosition(SectionCanvas); 
      rect = new System.Windows.Shapes.Rectangle 
      { 
       Stroke = brushColor, 
       StrokeDashArray = new DoubleCollection { 2, 2 }, 
       Tag = "rectangle" 
      };  
     Canvas.SetLeft(rect, startPos.X); 
       Canvas.SetTop(rect, startPos.X); 
       SectionCanvas.Children.Add(rect); 
     } 

private void Canvas_MouseMove(object sender, MouseEventArgs e) 
     { 

       currentPos = e.GetPosition(SectionCanvas); 

       var x = Math.Min(currentPos.X, startPos.X); 
       var y = Math.Min(currentPos.Y, startPos.Y); 

       var w = Math.Max(currentPos.X, startPos.X) - x; 
       var h = Math.Max(currentPos.Y, startPos.Y) - y; 

       rect.Width = w; 
       rect.Height = h; 

       Canvas.SetLeft(rect, x); 
       Canvas.SetTop(rect, y); 

     } 

    private void Canvas_MouseUp(object sender, MouseButtonEventArgs e) 
     {         
       if(rect == null) 
       { 
        MessageBox.Show("Could not capture section, Please try again"); 
        return; 
       } 
       endPos = e.GetPosition(SectionCanvas); 
       IEnumerable<Rect> coordinates = rectCollection.Select(r => new Rect(Canvas.GetLeft(r), Canvas.GetTop(r), r.Width, r.Height)); 
       Rect newCordinates = new Rect(Canvas.GetLeft(rect), Canvas.GetTop(rect), rect.Width, rect.Height);     
       if (coordinates.Any(c => c.IntersectsWith(newCordinates))))) 
       { 
        MessageBox.Show("New Rectangle intersects with existing rectangle"); 
        Canvas.Children.Remove(rect); 
        return; 
       } 
       rectCollection.Add(rect); 
       rect = null;  

       foreach(Point p in tempCollection) 
        { 
         if((startPos.X <= (p.X + 10) && startPos.X >= (p.X -10))) 
         { 
          startPos.X = p.X; 
         } 
         if(endPos.X <= (p.X + 10) && endPos.X >= (p.X - 10)) 
         { 
          var x1 = Math.Max(endPos.X,p.X) - Math.Min(endPos.X, p.X); 
          var w1 = startPos.X - x1; 
          endPos.X = p.X; 
          startPos.X = w1; 
         } 
         if ((startPos.Y <= (p.Y + 10) && startPos.Y >= (p.Y - 10))) 
         { 
          startPos.Y = p.Y; 
         } 

         if (endPos.Y <= (p.Y + 10) && endPos.Y >= (p.Y - 10)) 
         { 
          var x1 = Math.Max(endPos.Y, p.Y) - Math.Min(endPos.Y, p.Y); 
          var w1 = startPos.Y - x1; 
          endPos.Y = p.Y; 
         } 
        } 
        var x = Math.Min(currentPos.X, startPos.X); 
        var y = Math.Min(currentPos.Y, startPos.Y); 

        var w = Math.Max(currentPos.X, startPos.X) - x; 
        var h = Math.Max(currentPos.Y, startPos.Y) - y; 

        rect.Width = w; 
        rect.Height = h; 

        rect.Stroke = Brushes.Coral; 

        Canvas.SetLeft(rect, x); 
        Canvas.SetTop(rect, y); 
        rect = null; 
        tempCollection.Add(startPos); 
        tempCollection.Add(endPos); 
      } 

위의 코드는 끝점 값을 변경할 때 작동하지 않습니다. 디버깅하는 동안 끝점 값이 변경되지만 그려진 사각형은 변경되지 않습니다. 나는 내가 뭘 잘못하고 있는지 알 수 없다.

+1

나는 어제 여기 여기와 같은 질문을 보았습니다. 이것은 Microsoft 인터뷰 질문입니까? – McGarnagle

+0

@McGarnagle : 당신은이 같은 괜찮은 질문을 보았습니다. 그 질문이 대답 되었습니까 ?? 그렇다면 링크는 어디에 있습니까 ?? – Sivasubramanian

+0

왜이 질문은 downvoted ?? 이미 존재하는 질문 인 경우 링크를 붙여 넣으십시오. 그 대답은 OP와 다른 사람들에게 유용 할 것입니다. 증거 없이는 다운 다운하지 마십시오. – Sivasubramanian

답변

0

나는 내 말에서 멍청한 실수였던 대답을 알아 냈다.

스냅 한 후 너비와 높이를 계산하는 동안 currentPos를 사용하고 대신 endPos를 사용해야합니다.

var x = Math.Min(endPos.X, startPos.X); 
var y = Math.Min(endPos.Y, startPos.Y); 

var w = Math.Max(endPos.X, startPos.X) - x; 
var h = Math.Max(endPos.Y, startPos.Y) - y; 
관련 문제