2010-07-15 9 views
12

Mi proyecto es .NET/WinForms.No permitir que ListView tenga cero elementos seleccionados

Tengo una vista de lista que siempre está llena de elementos. Me gustaría tener una selección siempre. Sin embargo, si hago clic en un área vacía debajo de los elementos de la vista de lista, pierde la selección.

La lista tiene selección múltiple = verdadero y ocultar selección = falso.

+1

duplicado: http://stackoverflow.com/questions/2382369/prevent-listview-to-lose-selected-item – Marek

+1

única Duplicar tema. Ese hilo no tiene una respuesta real. –

+1

Y la respuesta updvoted más alta de ese subproceso es para WPF, esto es WinForms. – GenericTypeTea

Respuesta

22

debe impedir que el control nativo de ver el clic del ratón para que no se anule la selección de un elemento. Agregue una nueva clase a su proyecto y pegue el código que se muestra a continuación. Compilar. Colóquelo desde la parte superior de la caja de herramientas en su formulario, reemplazando el existente.

using System; 
using System.Drawing; 
using System.Windows.Forms; 

class MyListView : ListView { 
    protected override void WndProc(ref Message m) { 
     // Swallow mouse messages that are not in the client area 
     if (m.Msg >= 0x201 && m.Msg <= 0x209) { 
      Point pos = new Point(m.LParam.ToInt32()); 
      var hit = this.HitTest(pos); 
      switch (hit.Location) { 
       case ListViewHitTestLocations.AboveClientArea : 
       case ListViewHitTestLocations.BelowClientArea : 
       case ListViewHitTestLocations.LeftOfClientArea : 
       case ListViewHitTestLocations.RightOfClientArea : 
       case ListViewHitTestLocations.None : 
        return; 
      } 
     } 
     base.WndProc(ref m); 
    } 
} 
+0

Gracias por su sugerencia, pero es un nivel demasiado bajo. Creo que volveré a seleccionar la configuración manual como se sugiere a continuación. – Alex

+2

Es extraño, consideraría "volver a establecer manualmente la selección de nuevo" un truco de bajo nivel. –

+0

Esta es una gran solución, pero tuve que convertirla en una clase pública para que funcione. – Hugoagogo

0

Debe controlar el evento SelectedIndexChanged de ListView y, en caso de que no haya un elemento seleccionado después de que ocurra este evento, vuelva a seleccionar mediante programación la última selección conocida.

0

El ListView tiene un evento SelectedIndexChanged. Escuche esto y luego consulte la propiedad listView.SelectedItems.Count; si es cero, seleccione el primer/último elemento seleccionado.

2

Como han dicho los demás, el evento SelectedIndexChanged es lo que debe ver, sin embargo, debe usarlo en colaboración con el evento ItemSelectionChanged. Aquí hay un código que acabo cociné:

// Holds the last selected index 
private int _previousIndex = -1; 

// Restores the previous selection if there are no selections 
private void listView1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    if (listView1.SelectedIndices.Count == 0) 
    { 
     if (_previousIndex >= 0) 
     { 
      listView1.SelectedIndices.Add(_previousIndex); 
     } 
    } 
} 

// Records the last selected index 
private void listView1_ItemSelectionChanged(object sender, 
       ListViewItemSelectionChangedEventArgs e) 
{ 
    if (e.IsSelected) 
    { 
     _previousIndex = e.ItemIndex; 
    } 
} 

Para fines de reutilización de código puro, que probablemente sea la pena poner este código en un nuevo control de usuario y tienen una propiedad que determina si se permite o no la última selección que se pierda:

public class CustomListView : ListView 
{ 

    protected CustomListView() 
    { 
     this.SelectedIndexChanged += new EventHandler(CustomListView_SelectedIndexChanged); 
     this.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(CustomListView_ItemSelectionChanged); 
    } 

    void CustomListView_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (this.MaintainLastSelection && this.SelectedIndices.Count == 0) 
     { 
      if (_previousIndex >= 0) 
      { 
       this.SelectedIndices.Add(_previousIndex); 
      } 
     } 
    } 

    void CustomListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) 
    { 
     if (e.IsSelected) 
     { 
      _previousIndex = e.ItemIndex; 
     } 
    } 

    private int _previousIndex = -1; 

    public bool MaintainLastSelection 
    { 
     get { return _maintainLastSelection; } 
     set { _maintainLastSelection = value; } 
    } 
    private bool _maintainLastSelection; 

} 
1

Este siguiente funciona si no necesita multiselección. Tiene la ventaja de no tener que rastrear qué elemento fue seleccionado por última vez.

private void ListViewAny_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    if ((sender as ListView).FocusedItem != null) 
    { 
     (sender as ListView).FocusedItem.Selected = true; 
    } 
} 
1
private void LV_MouseUp(object sender, MouseEventArgs e) 
    { 
     if (LV.FocusedItem != null) 
     { 
      if (LV.SelectedItems.Count == 0) 
       LV.FocusedItem.Selected = true; 
     } 
    } 

(sin selección múltiple)

Cuestiones relacionadas