2011-05-17 33 views

Respuesta

9

Cuando implemente arrastrar y soltar en un control treeview, necesita admitir algún tipo de funcionalidad de desplazamiento automático. Por ejemplo, cuando arrastra un elemento desde un nodo de árbol visible, y el nodo de árbol de destino está fuera de la vista actual de la vista de árbol, el control debería desplazarse automáticamente hacia arriba o hacia abajo dependiendo de la dirección del mouse.

El control Treeview de Windows Forms no incluye funcionalidad incorporada para lograr esto. Sin embargo, es bastante fácil implementar esto usted mismo.

Paso 1: Obtenga su arrastre vista de árbol y colocar el código de trabajo

Asegúrese de arrastrar y soltar su vista de árbol código funciona correctamente sin desplazamiento automático. Consulte los temas en esta carpeta para obtener más información sobre cómo implementar arrastrar y soltar en una vista de árbol.

Paso 2: Agregar una definición para la función SendMessage

Con el fin de contar la vista de árbol para desplazarse hacia arriba o hacia abajo, es necesario llamar a la función de API de Windows SendMessage(). Para ello, agregue el siguiente código de la parte superior de su clase:

// Make sure you have the correct using clause to see DllImport: 
// using System.Runtime.InteropServices; 
[DllImport("user32.dll")] 
    private static extern int SendMessage (IntPtr hWnd, int wMsg, int wParam, 
     int lParam); 

Paso 3: Gancho en el DragScroll Evento

En el caso DragScroll, determinar dónde está el cursor del ratón está en relación con la parte superior y parte inferior del control treeview. Luego llame a SendMessage para desplazarse como apropiado.

// Implement an "autoscroll" routine for drag 
// and drop. If the drag cursor moves to the bottom 
// or top of the treeview, call the Windows API 
// SendMessage function to scroll up or down automatically. 
private void DragScroll (
    object sender, 
    DragEventArgs e) 
{ 
    // Set a constant to define the autoscroll region 
    const Single scrollRegion = 20; 

    // See where the cursor is 
    Point pt = TreeView1.PointToClient(Cursor.Position); 

    // See if we need to scroll up or down 
    if ((pt.Y + scrollRegion) > TreeView1.Height) 
    { 
     // Call the API to scroll down 
     SendMessage(TreeView1.Handle, (int)277, (int)1, 0); 
    } 
    else if (pt.Y < (TreeView1.Top + scrollRegion)) 
    { 
     // Call thje API to scroll up 
     SendMessage(TreeView1.Handle, (int)277, (int)0, 0); 
} 

Tomado de here.

+0

Excellent post !!! – Pacman

+0

Quizás cambie '(TreeView1.Top + scrollRegion)' a '(scrollRegion)'. En mi opinión, no necesitas el valor superior. Primero probé con la adición de TreeView1.Top (la vista de árbol está en la parte inferior de mi formulario) y el inicio de proceso de desplazamiento en el medio de la vista de árbol. Así que eliminé TreeView1.Top y el conjunto de inicio de desplazamiento en la parte superior de mi vista de árbol. – daniel

+0

@shaahin, ¿podría publicar las definiciones de macro de winapi reales? Sé que 277 es WM_VSCROLL, pero no puedo entender el 1 y el 0 de los archivos de encabezado. –

20

Más o menos lo mismo que el anterior, pero sin ese error "superior" y un poco más simple de usar en proyectos más grandes.

Añadir esta clase a su proyecto:

public static class NativeMethods 
{ 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

    public static void Scroll(this Control control) 
    { 
     var pt = control.PointToClient(Cursor.Position); 

     if ((pt.Y + 20) > control.Height) 
     { 
      // scroll down 
      SendMessage(control.Handle, 277, (IntPtr) 1, (IntPtr) 0); 
     } 
     else if (pt.Y < 20) 
     { 
      // scroll up 
      SendMessage(control.Handle, 277, (IntPtr) 0, (IntPtr) 0); 
     } 
    } 
} 

Después, simplemente suscribirse al evento DragOver de la vista de árbol (o cualquier otro control/control personalizado que desea scrolling habilitado mientras arrastrar/soltar) y llamar al desplazamiento () método.

private void treeView_DragOver(object sender, DragEventArgs e) 
    { 
     treeView.Scroll(); 
    } 
+0

@Vedran ¡Esto es genial! pero, ¿hay alguna manera de hacer que el TV se desplace un poco más lento? El mío parece ir un poco rápido ...? – MaxOvrdrv

Cuestiones relacionadas