2009-11-26 5 views
6

이미지 크기가 이미지의 전체 크기로 커지도록 그림 상자를 자동 크기로 설정했습니다.어떻게 자동으로 그림 상자를 노출하도록 패널을 스크롤 할 수 있습니까?

그림 상자는 그림이 패널보다 클 때 스크롤 막대가 표시되도록 autoScroll = true 인 패널에 있습니다.

사용자가 이미지의 끌기를 클릭하여 이미지의 위치를 ​​변경함으로써 프로그래밍 방식으로 패널을 스크롤하는 방법은 무엇입니까?

MouseMove 이벤트를 사용하여 마우스의 마지막 X 및 Y 위치를 캡처하고 마우스의 이동량을 계산하고 패널의 수직 및 수평 스크롤 값을 조정 해 보았습니다.

이미지가 주위를 움직이지만 장소를 뛰어 넘어 예기치 않게 스크롤됩니다.

내가 어떻게 이것을 달성 할 수 있습니까?

여기에 내 마우스 이벤트에이 무슨 ...

private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (dragging) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      // move the image inverse to direction dragged 
      int horizontalChange = (e.X - startingX) * -1; 
      int newHorizontalPos = panel1.HorizontalScroll.Value + horizontalChange; 

      if (newHorizontalPos < panel1.HorizontalScroll.Minimum) 
      { 
       newHorizontalPos = panel1.HorizontalScroll.Minimum; 
       horizontalChange = 0; 
      } 

      if (newHorizontalPos > panel1.HorizontalScroll.Maximum) 
      { 
       newHorizontalPos = panel1.HorizontalScroll.Maximum; 
       horizontalChange = 0; 
      } 

      panel1.HorizontalScroll.Value = newHorizontalPos; 

      int verticalChange = (e.Y - startingY); 
      // move the image inverse to direction dragged 
      int newverticalPos = panel1.VerticalScroll.Value + verticalChange * -1; 

      if (newverticalPos < panel1.VerticalScroll.Minimum) 
      { 
       newverticalPos = panel1.VerticalScroll.Minimum; 
       verticalChange = 0; 
      } 

      if (newverticalPos > panel1.VerticalScroll.Maximum) 
      { 
       newverticalPos = panel1.VerticalScroll.Maximum; 
       verticalChange = 0; 
      } 

      panel1.VerticalScroll.Value = newverticalPos; 
     } 
    } 

    startingX = e.X; 
    startingY = e.Y; 
} 

내 논리는 잘못인가, 아니면 패널의 스크롤 기능에 대한 이해가 잘못?

답변

4

필자는 본능이 정확하다고 생각하지만 실수는 스크롤 가능한 패널 내에서 PictureBox를 이동하는 대신 스크롤바를 조정하려고 시도하는 것입니다.

MouseMove를 가로 채고 마우스 동작 델타로 PictureBox의 Location 속성을 조정해야합니다. 스크롤바가 이미지의 새 위치를 반영하도록 자동으로 업데이트되어야합니다.

코드를 업데이트 (테스트되지 않은) 다음 그래도 같이 보일 것입니다 :

private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (dragging) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      int horizontalChange = (e.X - startingX) * -1; // move the image inverse to direction dragged 

      int verticalChange = (e.Y - startingY); 

      pictureBox1.Left += horizontalChange; 
      pictureBox1.Top += verticalChange; 
     } 
    } 

    startingX = e.X; 
    startingY = e.Y; 
} 

(또한, 나는 드래그의 시작 부분에서 시작 마우스와의 PictureBox 위치를 기록하기가 상대적으로 업데이트하는 경향 것 위의 코드와 같이 증분 변경을하지 않고 각 MouseMove 이벤트의 시작 위치 (원래 코드에서도 마찬가지입니다.) 이유는 무엇이든 예상치 못한 값이있는 경우 일시적인 효과 만 발생하기 때문입니다. 다음번의 좋은 행사는 자기 수정 될 것입니다.)

+0

감사합니다. 나는이 접근법을 연구하고있다. 그림 상자를 왼쪽이나 위쪽으로 이동하면 패널 컨트롤에 스크롤 막대가 표시되지 않습니다. - –

+0

오, 이상합니다. 자동 스크롤이 켜져 있어야합니다. –

5

행동으로 인해 점프하고 있습니다. f 패널을 스크롤하면 스크롤 량만큼 마우스 위치가 사라집니다.

Point realPos = new Point(e.X + panel1.AutoScrollPosition.X, 
    e.Y + panel1.AutoScrollPosition.Y); 

그림 상자 '위치 속성은 가정 (0, 0) :이 같은 (패널의 왼쪽 상단 모서리에서 상대적으로) "진짜"마우스 위치를 얻을 수 있습니다. 패널을 스크롤하는 가장 좋은 방법은 AutoScrollPosition 속성을 설정하는 것입니다.

2

MouseMove 이벤트에서 패널의 AutoScrollPosition을 설정할 수 있습니다. 테스트하고 잘 작동합니다.

panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X - e.X + startPoint.X, -panel1.AutoScrollPosition.Y - e.Y + startPoint.Y); 
관련 문제