2009-04-30 5 views

Respuesta

69

Aquí hay una aplicación rápida y sucia. Básicamente creé un Formulario con un botón y un ListBox. Al hacer clic en el botón, el ListBox se llena con la fecha de los próximos 20 días (tuvo que usar algo solo para probar). Luego, permite arrastrar y soltar dentro del ListBox para reordenar:

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
      this.listBox1.AllowDrop = true; 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      for (int i = 0; i <= 20; i++) 
      { 
       this.listBox1.Items.Add(DateTime.Now.AddDays(i)); 
      } 
     } 

     private void listBox1_MouseDown(object sender, MouseEventArgs e) 
     { 
      if (this.listBox1.SelectedItem == null) return; 
      this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move); 
     } 

     private void listBox1_DragOver(object sender, DragEventArgs e) 
     { 
      e.Effect = DragDropEffects.Move; 
     } 

     private void listBox1_DragDrop(object sender, DragEventArgs e) 
     { 
      Point point = listBox1.PointToClient(new Point(e.X, e.Y)); 
      int index = this.listBox1.IndexFromPoint(point); 
      if (index < 0) index = this.listBox1.Items.Count-1; 
      object data = e.Data.GetData(typeof(DateTime)); 
      this.listBox1.Items.Remove(data); 
      this.listBox1.Items.Insert(index, data); 
     } 
+6

Esto fue excelente gracias. Hay dos (muy pequeñas) En _MouseDown, la selección no cambia antes de que se active el evento, por lo que debe llamar a IndexFromPoint para obtener la selección actual (y comprobar que -1 significa en la parte inferior de la lista). Sin embargo, X y Y ya son coordenadas del cliente, por lo que no debe llamar a PointToClient En _DragDrop también debe verificar si el índice es -1, lo que indica que se deja caer al final de la lista e ignora la caída o mueve el elemento al final de él enumera como mejor te parezca. Estas dos cosas aparte, esta es exactamente la solución simple que estaba buscando. –

+4

También me encantó este pequeño código de muestra. Encontré los mismos errores que Gareth y edité la respuesta para eliminarlos, con suerte. –

+0

funciona perfecto para mí – lostcitizen

3

La primera vez que se tarda unas horas si nunca se implementó arrastrar y soltar, se desea hacer las cosas bien y tener que leer los documentos. Especialmente la retroalimentación inmediata y la restauración de la lista si el usuario cancela la operación requieren algunas reflexiones. Encapsular el comportamiento en un control de usuario reutilizable también llevará algo de tiempo.

Si nunca ha hecho la función de arrastrar y soltar, eche un vistazo a este drag and drop example desde MSDN. Este sería un buen punto de partida y le tomará tal vez medio día lograr que la cosa funcione.

0

Una alternativa es utilizar el control the list-view, que es el control que Explorer utiliza para mostrar el contenido de las carpetas. Es más complicado, pero implementa el arrastre de elementos para ti.

+0

... y no soporta cosas simples como enlace de datos los elementos de la lista :( – nathanchere

+0

... ni tampoco arrastrando el trabajo cuando se muestra en la lista o la vista de detalle. – nathanchere

2

7 Years Late. Pero para alguien nuevo, aquí está el código.

private void listBox1_MouseDown(object sender, MouseEventArgs e) 
    { 
     if (this.listBox1.SelectedItem == null) return; 
     this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move); 
    } 

    private void listBox1_DragOver(object sender, DragEventArgs e) 
    { 
     e.Effect = DragDropEffects.Move; 
    } 

    private void listBox1_DragDrop(object sender, DragEventArgs e) 
    { 
     Point point = listBox1.PointToClient(new Point(e.X, e.Y)); 
     int index = this.listBox1.IndexFromPoint(point); 
     if (index < 0) index = this.listBox1.Items.Count - 1; 
     object data = listBox1.SelectedItem; 
     this.listBox1.Items.Remove(data); 
     this.listBox1.Items.Insert(index, data); 
    } 

    private void itemcreator_Load(object sender, EventArgs e) 
    { 
     this.listBox1.AllowDrop = true; 
    } 
Cuestiones relacionadas