2009-04-30 14 views

risposta

69

Ecco un'app veloce e sporca. Fondamentalmente ho creato un modulo con un pulsante e un ListBox. Al clic del pulsante, la ListBox viene popolata con la data dei prossimi 20 giorni (doveva usare qualcosa solo per il test). Quindi, consente il trascinamento all'interno del ListBox per il riordino:

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

Questo è stato grande ringraziamento. Ci sono due (molto minore) In _MouseDown, la selezione non cambia prima che l'evento venga attivato, quindi è necessario chiamare IndexFromPoint per ottenere la selezione corrente (e controllare il significato di -1 nella parte inferiore dell'elenco). Qui però, X e Y sono già coordinate client quindi non chiami PointToClient In _DragDrop è inoltre necessario verificare se l'indice è -1 che indica di lasciare la parte inferiore dell'elenco e ignorare la caduta o spostare l'elemento nella parte inferiore di t elenca come meglio credi. Queste due cose a parte però, questa è esattamente la soluzione semplice che cercavo. –

+4

Adora anche questo piccolo esempio di codice. Ho trovato gli stessi bug di Gareth e ho modificato la risposta per rimuoverli, si spera. –

+0

funziona perfettamente per me – lostcitizen

3

La prima volta che occorrono alcune ore se non è stato implementato il trascinamento della selezione, è necessario eseguire correttamente le operazioni e leggere i documenti. Soprattutto il feedback immediato e il ripristino dell'elenco se l'utente annulla l'operazione richiede alcune riflessioni. Anche incapsulare il comportamento in un controllo utente riutilizzabile richiederà del tempo.

Se non si è mai eseguito il trascinamento della selezione, dare un'occhiata a questo drag and drop example da MSDN. Questo sarebbe un buon punto di partenza e ci vorrebbe forse mezza giornata per far funzionare la cosa.

0

Un'alternativa utilizza il controllo the list-view, che viene utilizzato dal controllo Explorer per visualizzare il contenuto delle cartelle. È più complicato, ma implementa l'elemento che si trascina per te.

+0

... e non supporta le cose semplici, come associazione dati le voci di elenco :( – nathanchere

+0

... né trascinando il lavoro quando viene visualizzata in elenco o un dettaglio vista. – nathanchere

2

7 anni di ritardo. Ma per chiunque sia nuovo, ecco il codice.

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