2009-11-26 14 views
6

Mam ustawione na obrazku pole AutoSize, aby obraz zmusił go do powiększenia do pełnego rozmiaru obrazu.Jak można spowodować, że panel przewija się programowo, aby odsłonić jego okno z autouzupełnianym obrazem?

Skrzynka z obrazkami znajduje się w panelu z funkcją autoScroll = true, dzięki czemu paski przewijania są wyświetlane, gdy obraz jest większy niż panel.

Jak programowo przewinąć panel, gdy użytkownik kliknie przeciągnięcia obrazu, zmieniając położenie obrazu.

Próbowałem użyć zdarzenia MouseMove, przechwytując ostatnie pozycje X i Y myszy, obliczając ruch myszy i dostosowując pionowe i poziome wartości przewijania panelu.

Przesuwa obraz, ale przeskakuje w każdym miejscu i przewija się nieprzewidywalnie.

Jak mogę to osiągnąć?

Oto co mam w moich zdarzeń myszy ...

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

Czy moja logika źle lub jest moje rozumienie przewijania funkcjonalności panelu źle?

Odpowiedz

4

Wierzę, że twój instynkt jest poprawny, ale twoim błędem jest próba dostosowania pasków przewijania zamiast przesuwania panelu PictureBox w przewijanym panelu.

Należy przechwycić MouseMove i wyregulować właściwość LocationBox za pomocą delty ruchu myszy - paski przewijania powinny być automatycznie aktualizowane, aby odzwierciedlić nowe położenie obrazu w nim.

Aktualizacja kod będzie wyglądał jak tho następujący (niesprawdzone):

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

(Również byłbym skłonny nagrać myszy rozpoczęcia i lokalizacje PictureBox na początku przeciągnij i aktualizować je w stosunku do tę pozycję początkową dla każdego zdarzenia MouseMove, a nie dokonywać przyrostowych zmian, jak powyższy kod (i oryginalny kod). Powodem tego jest to, że jeśli wystąpią jakiekolwiek nieoczekiwane wartości, z jakiegokolwiek powodu, spowoduje to jedynie efekt przejściowy - następne dobre wydarzenie samo się poprawi.)

+0

Dzięki. Pracuję z tym podejściem. Panel sterowania nie pokazuje pasków przewijania, jeśli przesuwasz ramkę graficzną z górnej lub lewej strony :-( –

+0

To dziwne - naprawdę powinno się, jeśli masz włączony AutoScroll. –

5

Skacze, ponieważ akt f przewijanie panelu spowoduje odrzucenie pozycji myszy o wartość przewijania. można dostać „prawdziwe” (względną pozycję myszy w lewym górnym rogu panelu) tak:

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

Zakładając box obraz”własność Lokalizacja jest (0, 0). Najlepszym sposobem przewinięcia panelu jest ustawienie jego właściwości AutoScrollPosition.

2

Możesz ustawić panel AutoScrollPosition w wydarzeniu MouseMove. Testowane i działa dobrze.

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