2011-08-05 13 views
13

Después de recorrer los artículos en línea, he creado este diseño para una aplicación de pantalla táctil basada en winforms que necesita un teléfono inteligente como el desplazamiento. La aplicación se ejecutará en una tableta portátil o en una pantalla táctil.cómo obtener un teléfono inteligente como desplazarse por una aplicación de pantalla táctil Winforms (panel de desplazamiento)

  • Pongo todo lo que quiero desplazar en un panel.
  • Conjunto de desplazamiento automático a verdadero (que mostrará las barras de desplazamiento)
  • Ahora poner todo este panel dentro de una caja de grupo
  • Reducir el cuadro de grupo hasta que las barras de desplazamiento están ocultos (oculta visualmente, no visible = false)

Ahora la parte divertida en la que estoy estancado. Creo que tengo que manejar el mousedown, mouseup & mousemove en el panel para establecer el autoscrollposition de modo que cuando alguien toca el panel y arrastra, lo hace es scroll magic. Por favor, ayuda a completar las pocas líneas de código en los siguientes talones de métodos. El msdn doc en autoscrollposition es muy confuso ya que devuelve números negativos pero debe establecerse en positivo con abs y lo que no.

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 = ?? 
} 

gracias

// ACTUALIZACIÓN - A continuación tengo con ensayo y error trabajando & código probado. (no refactorizado). Si alguien tiene una solución más elegante, publique.

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 

    } 

Respuesta

3

Esta es mi manera de utilizar IMessageFilter. Para todos los que buscan una solución. En primer lugar hay que aplicar un filtro que va a escuchar a todos los eventos de la aplicación:

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

entonces usted tiene que registrar este filtro para que Programa:

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

y ahora se puede escuchar los eventos globales de ratón y desplazar el panel desplazable de esta manera:

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

y como componente:

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

Utilicé el código que OP publicó pero me pareció que no funciona si hay elementos en el panel como etiquetas. Para hacer que esto funcione más fluidamente, cambié.

e.Location 

a

PointToClient(Cursor.Position) 

y luego tuvo todos los objetos dentro del panel también llamar a la mousedown y eventos mousemove. De esta forma, no importa dónde haga clic, debería moverse.

0

Para la publicación original, teniendo en cuenta la respuesta Funeral barato.

Esta versión es más simple y más fluida al tacto (considera la velocidad de movimiento del dedo pero sin tener en cuenta el efecto de desplazarse aún después de quitar el dedo, como mover pero apresurarse (tal vez lo haga cuando tenga tiempo)))

Obras para un panel o FlowLayoutPanel

crear un formulario e insertar un FlowLayoutPanel en él.

código

Forma:

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 

TIP: Para ocultar los rollos de la FlowLayoutPanel (o panel), crear un control de usuario que hereda de FlowLayoutPanel (o panel) y:

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

Este la solución parece ser la mejor y la más comúnmente aceptada; sin embargo, si se desplaza hacia abajo y toca el control de flujo real detrás de los botones (intenté hacer esto para que hubiera espacio vacío), entonces tener que presionar dos veces el botón para que el desplazamiento se reanude. Al reiniciar la aplicación se restaura la funcionalidad de desplazamiento similar a la del teléfono. Me pregunto si alguien más lo ha visto o lo ha descubierto, pruébalo con tus aplicaciones y mira si también es así. Modifiqué el fragmento de arriba para que puedas comenzar un nuevo proyecto, copiarlo y pegarlo en el código de form1 y presionar ejecutar.

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

Publicar una respuesta no debe hacer una nueva pregunta para cualquier persona que visite el sitio sobre cómo resolver un problema de código. Si tiene un problema con un fragmento de código, intente hacer una pregunta. –

Cuestiones relacionadas