2011-08-05 13 views
13

Po przejrzeniu artykułów online wymyśliłem ten projekt dla aplikacji z ekranem dotykowym, która potrzebuje smartfonu jak przewijanie. Sama aplikacja będzie działać na laptopie z tabletem lub na pulpicie dotykowym.jak zdobyć smartfona jak przewijanie dla aplikacji z ekranem dotykowym WinForm (przewijany panel)

  • Położyłem wszystko, co chcę przewinąć na panelu.
  • Set Autoscroll true (który pokaże przewijania)
  • Teraz umieścić ten cały panel wewnątrz groupbox
  • Zwężenie groupbox aż paski przewijania są ukryte (wizualnie ukryty, niewidoczny = false)

Teraz zabawa, w którą utknąłem. Myślę, że muszę obsłużyć mousedown, mouseup & mousemove na panelu, aby ustawić autoprzestrzeń tak, że gdy ktoś dotknie panelu i przeciągnie, zrobi to magia przewijania. Proszę pomóż wypełnić kilka linii kodu w poniższych informacjach o metodach. msdn doc w autoprzeźroczystej pozycji jest bardzo mylące, ponieważ zwraca liczby ujemne, ale musi być ustawione na dodatnie z abs, a co nie.

Point mouseDownPoint; 
Point mouseUpPoint; 
Point mouseDragPoint; 
private void myPanel_MouseDown(object sender, MouseEventArgs e) 
{ 
    this.mouseDownPoint = e.Location; 
    Console.WriteLine("Mouse down at {0}", e.location); 
} 

private void myPanel_MouseUp(object sender, MouseEventArgs e) 
{ 
    this.mouseUpPoint = e.Location; 
    this.mouseDownPoint = new Point(); //will set for IsEmpty check 
    Console.WriteLine("Mouse Up at {0}", e.location); 
} 

private void myPanel_MouseMove(object sender, MouseEventArgs e) 
{ 
    Console.WriteLine("Mouse at {0}", e.location); 
    if (mouseDownPoint.IsEmpty()) //finger is off the touchscreen 
     return; 
    myPanel.Autocrollposition = ?? 
} 

dziękuję

// UPDATE - Poniżej mam z prób i błędów pracy & przetestowany kod. (nie refaktoryzowane). Jeśli ktoś ma bardziej eleganckie rozwiązanie, opublikuj.

Point mouseDownPoint; 
    private void innerpanel_MouseDown(object sender, MouseEventArgs e) 
    { 
     if (e.Button == MouseButtons.Left) 
      this.mouseDownPoint = e.Location; 
    } 

    private void innerpanel_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (e.Button != MouseButtons.Left) 
      return; 
     if ((mouseDownPoint.X == e.Location.X) && (mouseDownPoint.Y == e.Location.Y)) 
      return; 

     Point currAutoS = innerpanel.AutoScrollPosition; 
     if (mouseDownPoint.Y > e.Location.Y) 
     { 
      //finger slide UP 
      if (currAutoS.Y != 0) 
       currAutoS.Y = Math.Abs(currAutoS.Y) - 5; 
     } 
     else if (mouseDownPoint.Y < e.Location.Y) 
     { 
      //finger slide down 
      currAutoS.Y = Math.Abs(currAutoS.Y) + 5; 
     } 
     else 
     { 
      currAutoS.Y = Math.Abs(currAutoS.Y); 
     } 

     if (mouseDownPoint.X > e.Location.X) 
     { 
      //finger slide left 
      if (currAutoS.X != 0) 
       currAutoS.X = Math.Abs(currAutoS.X) - 5; 
     } 
     else if (mouseDownPoint.X < e.Location.X) 
     { 
      //finger slide right 
      currAutoS.X = Math.Abs(currAutoS.X) + 5; 
     } 
     else 
     { 
      currAutoS.X = Math.Abs(currAutoS.X); 
     } 
     innerpanel.AutoScrollPosition = currAutoS; 
     mouseDownPoint = e.Location; //IMPORTANT 

    } 

Odpowiedz

3

Oto mój sposób korzystania z IMessageFilter. Dla wszystkich, którzy szukają solutiionu. Najpierw trzeba realizować filtr, który będzie nasłuchiwał wszystkich zdarzeń aplikacji:

internal class MouseFilter : IMessageFilter 
{ 
    private const int WM_LBUTTONDOWN = 0x0201; 
    private const int WM_LBUTTONUP = 0x0202; 
    private const int WM_MOUSEMOVE = 0x0200; 

    /// <summary> 
    ///  Filtert eine Meldung, bevor sie gesendet wird. 
    /// </summary> 
    /// <param name="m">Die zu sendende Meldung. Diese Meldung kann nicht geändert werden.</param> 
    /// <returns> 
    ///  true, um die Meldung zu filtern und das Senden zu verhindern. false, um das Senden der Meldung bis zum nächsten Filter oder Steuerelement zu ermöglichen. 
    /// </returns> 
    public bool PreFilterMessage(ref Message m) 
    { 
     Point mousePosition = Control.MousePosition; 
     var args = new MouseFilterEventArgs(MouseButtons.Left, 0, mousePosition.X, mousePosition.Y, 0); 

     switch (m.Msg) 
     { 
      case WM_MOUSEMOVE: 
       if (MouseFilterMove != null) 
       { 
        MouseFilterMove(Control.FromHandle(m.HWnd), args); 
       } 
       break; 

      case WM_LBUTTONDOWN: 
       if (MouseFilterDown != null) 
       { 
        MouseFilterDown(Control.FromHandle(m.HWnd), args); 
       } 
       break; 

      case WM_LBUTTONUP: 
       if (MouseFilterUp != null) 
       { 
        MouseFilterUp(Control.FromHandle(m.HWnd), args); 
       } 
       break; 
     } 

     // Always allow message to continue to the next filter control 
     return args.Handled; 
    } 

    /// <summary> 
    ///  Occurs when [mouse filter up]. 
    /// </summary> 
    public event MouseFilterEventHandler MouseFilterUp; 

    /// <summary> 
    ///  Occurs when [mouse filter down]. 
    /// </summary> 
    public event MouseFilterEventHandler MouseFilterDown; 

    /// <summary> 
    ///  Occurs when [mouse filter move]. 
    /// </summary> 
    public event MouseFilterMoveEventHandler MouseFilterMove; 
} 

internal delegate void MouseFilterEventHandler(object sender, MouseFilterEventArgs args); 

internal delegate void MouseFilterMoveEventHandler(object sender, MouseFilterEventArgs args); 

internal class MouseFilterEventArgs 
{ 
    /// <summary> 
    ///  Initializes a new instance of the <see cref="MouseFilterEventArgs" /> class. 
    /// </summary> 
    /// <param name="mouseButton">The mouse button.</param> 
    /// <param name="clicks">The clicks.</param> 
    /// <param name="x">The x.</param> 
    /// <param name="y">The y.</param> 
    /// <param name="delta">The delta.</param> 
    public MouseFilterEventArgs(MouseButtons mouseButton, int clicks, int x, int y, int delta) 
    { 
     Button = mouseButton; 
     Clicks = clicks; 
     X = x; 
     Y = y; 
     Delta = delta; 
     Handled = false; 
    } 

    /// <summary> 
    ///  Gets or sets the button. 
    /// </summary> 
    /// <value> 
    ///  The button. 
    /// </value> 
    public MouseButtons Button { get; set; } 

    /// <summary> 
    ///  Gets or sets a value indicating whether this <see cref="MouseFilterEventArgs" /> is handled. 
    /// </summary> 
    /// <value> 
    ///  <c>true</c> if handled; otherwise, <c>false</c>. 
    /// </value> 
    public bool Handled { get; set; } 

    /// <summary> 
    ///  Gets or sets the X. 
    /// </summary> 
    /// <value> 
    ///  The X. 
    /// </value> 
    public int X { get; set; } 

    /// <summary> 
    ///  Gets or sets the Y. 
    /// </summary> 
    /// <value> 
    ///  The Y. 
    /// </value> 
    public int Y { get; set; } 

    /// <summary> 
    ///  Gets or sets the clicks. 
    /// </summary> 
    /// <value> 
    ///  The clicks. 
    /// </value> 
    public int Clicks { get; set; } 

    /// <summary> 
    ///  Gets or sets the delta. 
    /// </summary> 
    /// <value> 
    ///  The delta. 
    /// </value> 
    public int Delta { get; set; } 
} 

Następnie trzeba zarejestrować ten filtr do ciebie Program:

static class Program 
{ 
    public static MouseFilter mouseFilter = new MouseFilter(); 

    /// <summary> 
    /// Der Haupteinstiegspunkt für die Anwendung. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.AddMessageFilter(mouseFilter); 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new MainForm()); 
    } 
} 

I teraz można słuchać na globalnych zdarzeń myszy i przewijać przewijalną panelu tak:

public partial class MainForm : Form 
{ 
    private bool _doTouchScroll; 
    private Point _mouseStartPoint = Point.Empty; 
    private Point _yourScrollablePanelStartPoint = Point.Empty; 

    /// <summary> 
    ///  Initializes a new instance of the <see cref="MainForm" /> class. 
    /// </summary> 
    public MainForm() 
    { 
     InitializeComponent(); 

     Program.mouseFilter.MouseFilterDown += mouseFilter_MouseFilterDown; 
     Program.mouseFilter.MouseFilterMove += mouseFilter_MouseFilterMove; 
     Program.mouseFilter.MouseFilterUp += mouseFilter_MouseFilterUp; 
    } 

    /// <summary> 
    ///  Handles the MouseFilterDown event of the mudmFilter control. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e"> 
    ///  The <see cref="MouseFilterEventArgs" /> instance containing the event data. 
    /// </param> 
    private void mouseFilter_MouseFilterDown(object sender, MouseFilterEventArgs e) 
    { 
     if (!_doTouchScroll && e.Button == MouseButtons.Left) 
     { 
      _mouseStartPoint = new Point(e.X, e.Y); 
      _yourScrollablePanelStartPoint = new Point(-yourScrollablePanel.AutoScrollPosition.X, 
               -yourScrollablePanel.AutoScrollPosition.Y); 
     } 
    } 

    /// <summary> 
    ///  Handles the MouseFilterMove event of the mudmFilter control. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e"> 
    ///  The <see cref="MouseFilterEventArgs" /> instance containing the event data. 
    /// </param> 
    private void mouseFilter_MouseFilterMove(object sender, MouseFilterEventArgs e) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      if (!_mouseStartPoint.Equals(Point.Empty)) 
      { 
       int dx = (e.X - _mouseStartPoint.X); 
       int dy = (e.Y - _mouseStartPoint.Y); 

       if (_doTouchScroll) 
       { 
        yourScrollablePanel.AutoScrollPosition = new Point(_yourScrollablePanelStartPoint.X - dx, 
                   _yourScrollablePanelStartPoint.Y - dy); 
       } 
       else if (Math.Abs(dx) > 10 || Math.Abs(dy) > 10) 
       { 
        _doTouchScroll = true; 
       } 
      } 
     } 
    } 

    /// <summary> 
    ///  Handles the MouseFilterUp event of the mudmFilter control. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e"> 
    ///  The <see cref="MouseFilterEventArgs" /> instance containing the event data. 
    /// </param> 
    private void mouseFilter_MouseFilterUp(object sender, MouseFilterEventArgs e) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      if (_doTouchScroll && !yourScrollablePanel.AutoScrollPosition.Equals(_yourScrollablePanelStartPoint) && 
       !_yourScrollablePanelStartPoint.Equals(Point.Empty)) 
      { 
       // dont fire Click-Event 
       e.Handled = true; 
      } 
      _doTouchScroll = false; 
      _mouseStartPoint = Point.Empty; 
      _yourScrollablePanelStartPoint = Point.Empty; 
     } 
    } 
} 
7

oraz jako składnik:

public partial class TouchableFlowLayoutPanel : FlowLayoutPanel 
{ 
    private bool _doTouchScroll; 
    private Point _mouseStartPoint = Point.Empty; 
    private Point _panelStartPoint = Point.Empty; 

    /// <summary> 
    ///  Initializes a new instance of the <see cref="TouchableFlowLayoutPanel" /> class. 
    /// </summary> 
    public TouchableFlowLayoutPanel() 
    { 
     InitializeComponent(); 

     Program.mouseFilter.MouseFilterDown += mouseFilter_MouseFilterDown; 
     Program.mouseFilter.MouseFilterMove += mouseFilter_MouseFilterMove; 
     Program.mouseFilter.MouseFilterUp += mouseFilter_MouseFilterUp; 
    } 

    /// <summary> 
    ///  Initializes a new instance of the <see cref="TouchableFlowLayoutPanel" /> class. 
    /// </summary> 
    /// <param name="container">The container.</param> 
    public TouchableFlowLayoutPanel(IContainer container) 
    { 
     container.Add(this); 

     InitializeComponent(); 

     Program.mouseFilter.MouseFilterDown += mouseFilter_MouseFilterDown; 
     Program.mouseFilter.MouseFilterMove += mouseFilter_MouseFilterMove; 
     Program.mouseFilter.MouseFilterUp += mouseFilter_MouseFilterUp; 
    } 

    /// <summary> 
    ///  Handles the MouseFilterDown event of the mouseFilter control. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e"> 
    ///  The <see cref="MouseFilterEventArgs" /> instance containing the event data. 
    /// </param> 
    private void mouseFilter_MouseFilterDown(object sender, MouseFilterEventArgs e) 
    { 
     if (!_doTouchScroll && e.Button == MouseButtons.Left) 
     { 
      _mouseStartPoint = new Point(e.X, e.Y); 
      _panelStartPoint = new Point(-AutoScrollPosition.X, 
               -AutoScrollPosition.Y); 
     } 
    } 

    /// <summary> 
    ///  Handles the MouseFilterMove event of the mouseFilter control. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e"> 
    ///  The <see cref="MouseFilterEventArgs" /> instance containing the event data. 
    /// </param> 
    private void mouseFilter_MouseFilterMove(object sender, MouseFilterEventArgs e) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      if (!_mouseStartPoint.Equals(Point.Empty)) 
      { 
       int dx = (e.X - _mouseStartPoint.X); 
       int dy = (e.Y - _mouseStartPoint.Y); 

       if (_doTouchScroll) 
       { 
        AutoScrollPosition = new Point(_panelStartPoint.X - dx, 
                _panelStartPoint.Y - dy); 
       } 
       else if (Math.Abs(dx) > 10 || Math.Abs(dy) > 10) 
       { 
        _doTouchScroll = true; 
       } 
      } 
     } 
    } 

    /// <summary> 
    ///  Handles the MouseFilterUp event of the mouseFilter control. 
    /// </summary> 
    /// <param name="sender">The source of the event.</param> 
    /// <param name="e"> 
    ///  The <see cref="MouseFilterEventArgs" /> instance containing the event data. 
    /// </param> 
    private void mouseFilter_MouseFilterUp(object sender, MouseFilterEventArgs e) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      if (_doTouchScroll && !AutoScrollPosition.Equals(_panelStartPoint) && 
       !_panelStartPoint.Equals(Point.Empty)) 
      { 
       // don't fire Click-Event 
       e.Handled = true; 
      } 
      _doTouchScroll = false; 
      _mouseStartPoint = Point.Empty; 
      _panelStartPoint = Point.Empty; 
     } 
    } 
} 

internal class MouseFilter : IMessageFilter 
{ 
    private const int WM_LBUTTONDOWN = 0x0201; 
    private const int WM_LBUTTONUP = 0x0202; 
    private const int WM_MOUSEMOVE = 0x0200; 

    /// <summary> 
    ///  Filtert eine Meldung, bevor sie gesendet wird. 
    /// </summary> 
    /// <param name="m">Die zu sendende Meldung. Diese Meldung kann nicht geändert werden.</param> 
    /// <returns> 
    ///  true, um die Meldung zu filtern und das Senden zu verhindern. false, um das Senden der Meldung bis zum nächsten Filter oder Steuerelement zu ermöglichen. 
    /// </returns> 
    public bool PreFilterMessage(ref Message m) 
    { 
     Point mousePosition = Control.MousePosition; 
     var args = new MouseFilterEventArgs(MouseButtons.Left, 0, mousePosition.X, mousePosition.Y, 0); 

     switch (m.Msg) 
     { 
      case WM_MOUSEMOVE: 
       if (MouseFilterMove != null) 
       { 
        MouseFilterMove(Control.FromHandle(m.HWnd), args); 
       } 
       break; 

      case WM_LBUTTONDOWN: 
       if (MouseFilterDown != null) 
       { 
        MouseFilterDown(Control.FromHandle(m.HWnd), args); 
       } 
       break; 

      case WM_LBUTTONUP: 
       if (MouseFilterUp != null) 
       { 
        MouseFilterUp(Control.FromHandle(m.HWnd), args); 
       } 
       break; 
     } 

     // Always allow message to continue to the next filter control 
     return args.Handled; 
    } 

    /// <summary> 
    ///  Occurs when [mouse filter up]. 
    /// </summary> 
    public event MouseFilterEventHandler MouseFilterUp; 

    /// <summary> 
    ///  Occurs when [mouse filter down]. 
    /// </summary> 
    public event MouseFilterEventHandler MouseFilterDown; 

    /// <summary> 
    ///  Occurs when [mouse filter move]. 
    /// </summary> 
    public event MouseFilterMoveEventHandler MouseFilterMove; 
} 

internal delegate void MouseFilterEventHandler(object sender, MouseFilterEventArgs args); 

internal delegate void MouseFilterMoveEventHandler(object sender, MouseFilterEventArgs args); 

internal class MouseFilterEventArgs 
{ 
    /// <summary> 
    ///  Initializes a new instance of the <see cref="MouseFilterEventArgs" /> class. 
    /// </summary> 
    /// <param name="mouseButton">The mouse button.</param> 
    /// <param name="clicks">The clicks.</param> 
    /// <param name="x">The x.</param> 
    /// <param name="y">The y.</param> 
    /// <param name="delta">The delta.</param> 
    public MouseFilterEventArgs(MouseButtons mouseButton, int clicks, int x, int y, int delta) 
    { 
     Button = mouseButton; 
     Clicks = clicks; 
     X = x; 
     Y = y; 
     Delta = delta; 
     Handled = false; 
    } 

    /// <summary> 
    ///  Gets or sets the button. 
    /// </summary> 
    /// <value> 
    ///  The button. 
    /// </value> 
    public MouseButtons Button { get; set; } 

    /// <summary> 
    ///  Gets or sets a value indicating whether this <see cref="MouseFilterEventArgs" /> is handled. 
    /// </summary> 
    /// <value> 
    ///  <c>true</c> if handled; otherwise, <c>false</c>. 
    /// </value> 
    public bool Handled { get; set; } 

    /// <summary> 
    ///  Gets or sets the X. 
    /// </summary> 
    /// <value> 
    ///  The X. 
    /// </value> 
    public int X { get; set; } 

    /// <summary> 
    ///  Gets or sets the Y. 
    /// </summary> 
    /// <value> 
    ///  The Y. 
    /// </value> 
    public int Y { get; set; } 

    /// <summary> 
    ///  Gets or sets the clicks. 
    /// </summary> 
    /// <value> 
    ///  The clicks. 
    /// </value> 
    public int Clicks { get; set; } 

    /// <summary> 
    ///  Gets or sets the delta. 
    /// </summary> 
    /// <value> 
    ///  The delta. 
    /// </value> 
    public int Delta { get; set; } 
} 

static class Program 
{ 
    public static MouseFilter mouseFilter = new MouseFilter(); 

    /// <summary> 
    /// Der Haupteinstiegspunkt für die Anwendung. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.AddMessageFilter(mouseFilter); 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new MainForm()); 
    } 
} 
2

Użyłem kodu OP opublikowanego, ale okazało się, że nie działa, jeśli są rzeczy z panelu jak etykiety. Żeby to sprawniej przebiegło, zmieniłem się.

e.Location 

do

PointToClient(Cursor.Position) 

a następnie miał wszystkie obiekty wewnątrz panelu również wywołać mousedown i mousemove wydarzenia. W ten sposób nie ważne, gdzie klikniesz, powinno się przesunąć.

0

Do oryginalnego postu, biorąc pod uwagę Cheap Funeral answer.

Ta wersja jest bardziej prosta i bardziej płynna w dotyku (bierze pod uwagę szybkość poruszania palcem, ale nie bierze pod uwagę efektu ciągłego przewijania po zdjęciu palca, np. Porusza się, ale przyspiesza (może zrobię to, mam czas))

pracuje dla panelu lub FlowLayoutPanel

Utwórz formę i wstawić FlowLayoutPanel na nim.

kod

Postać:

Public Class Form1 

Private Function GenerateButton(pName As String) As Button 
    Dim mResult As New Button 
    With mResult 
     .Name = pName 
     .Text = pName 
     .Width = FlowPanel.Width 
     .Height = 100 
     .Margin = New Padding(0) 
     .Padding = New Padding(0) 
     .BackColor = Color.CornflowerBlue 
     AddHandler .MouseDown, AddressOf Button_MouseDown 
     AddHandler .MouseMove, AddressOf Button_MouseMove 
    End With 

    Return mResult 
End Function 



Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    FlowPanel.Padding = New Padding(0) 
    FlowPanel.Margin = New Padding(0) 
    Dim i As Integer 
    For i = 1 To 100 
     FlowPanel.Controls.Add(GenerateButton("btn" & i.ToString)) 
    Next 
End Sub 

Dim myMouseDownPoint As Point 
Dim myCurrAutoSMouseDown As Point 
Private Sub Button_MouseDown(sender As Object, e As MouseEventArgs) Handles FlowPanel.MouseDown 
    myMouseDownPoint = PointToClient(Cursor.Position) 
    myCurrAutoSMouseDown = FlowPanel.AutoScrollPosition 
End Sub 

Private Sub Button_MouseMove(sender As Object, e As MouseEventArgs) Handles FlowPanel.MouseMove 
    If e.Button = Windows.Forms.MouseButtons.Left Then 
     Dim mLocation As Point = PointToClient(Cursor.Position) 
     If myMouseDownPoint <> mLocation Then 
      Dim mCurrAutoS As Point 
      Dim mDeslocation As Point = myMouseDownPoint - mLocation 
      mCurrAutoS.X = Math.Abs(myCurrAutoSMouseDown.X) + mDeslocation.X 
      mCurrAutoS.Y = Math.Abs(myCurrAutoSMouseDown.Y) + mDeslocation.Y 

      FlowPanel.AutoScrollPosition = mCurrAutoS 

     End If 
    End If 
End Sub 

Wskazówka Aby ukryć zwoje FlowLayoutPanel (lub panelu), tworzenie usercontrol która dziedziczy FlowLayoutPanel (lub panel) oraz:

Imports System.Runtime.InteropServices 

Public Class FlowLayoutPanelExt 
Inherits FlowLayoutPanel 


<DllImport("user32.dll")> _ 
Private Shared Function ShowScrollBar(hWnd As IntPtr, wBar As Integer, bShow As Boolean) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

Private Enum ScrollBarDirection 
    SB_HORZ = 0 
    SB_VERT = 1 
    SB_CTL = 2 
    SB_BOTH = 3 
End Enum 

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) 
    If Me.Visible Then 
     ShowScrollBar(Me.Handle, CInt(ScrollBarDirection.SB_BOTH), False) 
     MyBase.WndProc(m) 
    End If 
End Sub 

Public Sub New() 

    ' This call is required by the designer. 
    InitializeComponent() 

    ' Add any initialization after the InitializeComponent() call. 
    Me.AutoScroll = True 
End Sub 

End Class 
0

ten rozwiązanie wydaje się najlepsze i najczęściej akceptowane - jednak jeśli przewiniesz na dół i dotkniesz faktycznego kontrolka przepływu za przyciskami (próbowałem zrobić to tak, aby było puste miejsce), to trzeba dwukrotnie dotknąć i przytrzymać przycisk przewijania do wznowienia. Ponowne uruchomienie aplikacji przywraca funkcjonalność przewijania przypominającą telefon. Zastanawiam się, czy ktokolwiek inny to widział, czy to wymyślił - spróbuj z aplikacjami i sprawdź, czy tak też jest. Zmodyfikowałem powyższy fragment, aby można było rozpocząć nowy projekt, skopiować i wkleić go do kodu form1 i uruchomić.

Public Class Form1 
     Dim FlowPanel As New FlowLayoutPanel 
     Private Function GenerateButton(ByVal pName As String) As Button 
      Dim mResult As New Button 
      With mResult 
       .Name = pName 
       .Text = pName 
       .Width = 128 
       .Height = 128 
       .Margin = New Padding(0) 
       .Padding = New Padding(0) 
       .BackColor = Color.CornflowerBlue 
       AddHandler .MouseDown, AddressOf Button_MouseDown 
       AddHandler .MouseMove, AddressOf Button_MouseMove 
      End With 

      Return mResult 
     End Function 



     Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load 

      Me.Width = 806 
      Me.Height = 480 
      FlowPanel.Padding = New Padding(0) 
      FlowPanel.Margin = New Padding(0) 
      ' FlowPanel.ColumnCount = Me.Width/(128 + 6) 
      FlowPanel.Dock = DockStyle.Fill 
      FlowPanel.AutoScroll = True 
      Me.Controls.Add(FlowPanel) 
      Dim i As Integer 
      For i = 1 To 98 
       FlowPanel.Controls.Add(GenerateButton("btn" & i.ToString)) 
      Next 
     End Sub 

     Dim myMouseDownPoint As Point 
     Dim myCurrAutoSMouseDown As Point 
     Private Sub Button_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) 
      myMouseDownPoint = PointToClient(Cursor.Position) 
      myCurrAutoSMouseDown = FlowPanel.AutoScrollPosition 
     End Sub 

     Private Sub Button_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) 
      If e.Button = Windows.Forms.MouseButtons.Left Then 
       Dim mLocation As Point = PointToClient(Cursor.Position) 
       If myMouseDownPoint <> mLocation Then 
        Dim mCurrAutoS As Point 
        Dim mDeslocation As Point = myMouseDownPoint - mLocation 
        mCurrAutoS.X = Math.Abs(myCurrAutoSMouseDown.X) + mDeslocation.X 
        mCurrAutoS.Y = Math.Abs(myCurrAutoSMouseDown.Y) + mDeslocation.Y 

        FlowPanel.AutoScrollPosition = mCurrAutoS 

       End If 
      End If 
     End Sub 
    End Class 
+0

Zamieszczanie odpowiedzi nie powinno zadawać nowych pytań osobom odwiedzającym witrynę w celu rozwiązania problemu z kodem. Jeśli masz problem z fragmentem kodu, spróbuj zadać pytanie. –

Powiązane problemy