2011-01-22 14 views
11

Estoy implementando algunas características de arrastrar y soltar en uno de mis controles que heredan de una vista de cuadrícula de datos. Básicamente, estoy arrastrando una fila desde algún lugar de la DGV y soltándola en otro lugar, reordenando las filas. Me he encontrado con un problema sin embargo. Si el DGV es demasiado grande como para que haya una barra de desplazamiento, ¿cómo puedo hacer que el DGV se desplace hacia arriba o hacia abajo mientras el usuario está en medio de una rueda de arrastre?¿Cómo puedo desplazarme programáticamente un control winform datagridview?

Sé cómo obtener la posición actual del mouse y también obtener la posición del rectángulo dgv y tal. Entonces, puedo averiguar fácilmente si estoy en la mitad superior o inferior del rectángulo ... Solo necesito una forma de desplazar el dgv mediante programación. Preferiría si no tuviera que seguir cambiando la celda seleccionada para hacer esto.

¿Alguna sugerencia?

Gracias

Isaac

Respuesta

18

Bueno, ya que esta es una vista de cuadro de datos ... Perdón por los 'winforms' en la pregunta ... pero podría hacer esto ... desplazándome hacia arriba o hacia abajo una fila.

Desplazarse hacia arriba:

this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex - 1 

de desplazamiento hacia abajo:

this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex + 1; 

Tienes que asegúrese de comprobar que los números no salen fuera de los límites sin embargo.

5

Es posible hacer que el uso de API de Windows mediante el envío de mensajes al control contarla para desplazarse hacia arriba o hacia abajo.

Aquí está el código, espero que ayuda a:

private const int WM_SCROLL = 276; // Horizontal scroll 
private const int WM_VSCROLL = 277; // Vertical scroll 
private const int SB_LINEUP = 0; // Scrolls one line up 
private const int SB_LINELEFT = 0;// Scrolls one cell left 
private const int SB_LINEDOWN = 1; // Scrolls one line down 
private const int SB_LINERIGHT = 1;// Scrolls one cell right 
private const int SB_PAGEUP = 2; // Scrolls one page up 
private const int SB_PAGELEFT = 2;// Scrolls one page left 
private const int SB_PAGEDOWN = 3; // Scrolls one page down 
private const int SB_PAGERIGTH = 3; // Scrolls one page right 
private const int SB_PAGETOP = 6; // Scrolls to the upper left 
private const int SB_LEFT = 6; // Scrolls to the left 
private const int SB_PAGEBOTTOM = 7; // Scrolls to the upper right 
private const int SB_RIGHT = 7; // Scrolls to the right 
private const int SB_ENDSCROLL = 8; // Ends scroll 

[DllImport("user32.dll",CharSet=CharSet.Auto)] 
private static extern int SendMessage(IntPtr hWnd, int wMsg,IntPtr wParam, IntPtr lParam); 

Ahora suponiendo que tiene un control de cuadro de texto en el formulario. Puede moverlo con:

SendMessage(textBox1.Handle,WM_VSCROLL,(IntPtr)SB_PAGEUP,IntPtr.Zero); //ScrollUp 
SendMessage(textBox1.Handle,WM_VSCROLL,(IntPtr)SB_PAGEDOWN,IntPtr.Zero); //ScrollDown 

Si esa solución general clásica no funciona para usted. Es posible que desee mirar FirstDisplayedScrollingRowIndex Propiedad y cambiarlo con respecto a la posición del mouse durante el arrastre.

+0

Gracias por esto. No lo he intentado ... el chico de arriba tiene una forma no winapi de hacer esto. –

+0

Lo intenté y no funcionó. ¡Lo siento! –

9

que puede hacer esto mediante el establecimiento HorizontalScrollingOffset/VerticalScrollingOffset del DataGridView

para establecer HorizontalScrollingOffset

dataGridView1.HorizontalScrollingOffset = dataGridView1.HorizontalScrollingOffset + 10; 

cheque

DataGridView.HorizontalScrollingOffset Property

y

para VerticalScrollingOffset se puede utilizar la reflexión

incluyen espacio de nombres System.Reflection

PropertyInfo verticalOffset = dataGridView1.GetType().GetProperty("VerticalOffset", BindingFlags.NonPublic | BindingFlags.Instance); 
      verticalOffset.SetValue(this.dataGridView1, 10, null); 
+2

VerticalScrollingOffset tiene propiedad de solo lectura. Así que solo puede 'obtener', no puede' establecer'. –

+0

No ambos, horizontal es {obtener; establecer;} Aunque no le ayudará de una manera u otra – deadlock

+0

@deadlock: Lo siento, marcó Vertical solo ... –

2

Es necesario implementar el evento DragOver. Compruebe si el mouse está ubicado cerca de la parte superior o inferior del control (use PointToClient). Cuando es así, habilite un temporizador con un intervalo de ~ 200 mseg. En el controlador de eventos Tick, desplácese por una fila en el DGV. Desactive el temporizador cuando el mouse no esté cerca y después de que DoDragDrop regrese. El usuario ahora puede desplazarse de manera fácil e intuitiva por la cuadrícula que se encuentra cerca de los extremos.

+0

Sí, ¡solo necesito descubrir cómo desplazarla por una fila! –

+0

Ah, el caballero de abajo tiene la solución. Ya tengo Dragover implementado, agregaré algún código para que se desplace de forma inteligente, como sugeriste. Gracias por su consejo de diseño Hans. –

+0

¡Realmente funciona bien incluso sin el temporizador! Parece que el movimiento de las filas de la grilla debajo del mouse es suficiente para seguir disparando el evento DragOver. – peterG

4
dgv.FirstDisplayedScrollingRowIndex = dgv.RowCount - 1; 
Cuestiones relacionadas