2010-03-04 33 views
7

Actualmente estoy trabajando en una vista de lista en winform C# y cada vez que hago clic en un espacio vacío en la vista de lista, se pierde el elemento seleccionado.evitar que la vista de lista pierda el elemento seleccionado

+0

WinForms o WPF? ¿Espacio vacío a la derecha o abajo? ¿Qué es lo que desea que suceda? – Grammarian

+0

posible duplicado de [No permitir que ListView tenga cero elementos seleccionados] (http://stackoverflow.com/questions/3255046/disallow-listview-to-have-zero-selected-items) –

+0

en propiedades ... HideSelection = False and FullRowSelect = True –

Respuesta

2

Pensé que había una propiedad que impedía que esto sucediera, pero ahora no puedo encontrarla.

Usted podría intentar esto:

private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    ListView listView = sender as ListView; 
    if (listView.SelectedItems.Count == 0) 
     foreach (object item in e.RemovedItems) 
      listView.SelectedItems.Add(item); 
} 
+1

Esto solo funcionará en WPF. – Grammarian

+1

@Grammarian: la pregunta no especificaba si era WPF, WinForms, ASP, Silverlight o cualquier otra cosa. Acabo de responder con la que tuve abierto en el IDE en este momento. ¡Debería publicar una respuesta con su tecnología de visualización C# favorita! :-) –

+0

de hecho su derecho. está en winforms – EdgarGad

1

Esto es mucho más difícil de hacer en Windows Forms que en WPF. WinForms tiene un evento SelectedIndexChanged que no le dice nada acerca de lo que ya estaba seleccionado, más se activa cada vez que se selecciona o deselecciona una fila.

lo tanto, si se selecciona una fila y se selecciona una fila diferente, recibe dos eventos: SelectedIndexChanged

  1. una después de la fila seleccionada no está seleccionada
  2. otra cuando se selecciona la nueva fila.

El problema es que, durante el evento # 1, el ListView no tiene nada seleccionado y no sabe si el evento # 2 que viene seleccionará la segunda fila.

Lo mejor que puede hacer es esperar hasta que su aplicación esté inactiva (algunos milisegundos después de que la selección haya cambiado), y si la vista de lista todavía no tiene nada seleccionado, vuelva a colocar la última fila seleccionada.

private void listView1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    ListView lv = (ListView)sender; 
    if (lv.SelectedIndices.Count == 0) 
    { 
     if (!this.appIdleEventScheduled) 
     { 
      this.appIdleEventScheduled = true; 
      this.listViewToMunge = lv; 
      Application.Idle += new EventHandler(Application_Idle); 
     } 
    } 
    else 
     this.lastSelectedIndex = lv.SelectedIndices[0]; 
} 

void Application_Idle(object sender, EventArgs e) 
{ 
    Application.Idle -= new EventHandler(Application_Idle); 
    this.appIdleEventScheduled = false; 
    if (listViewToMunge.SelectedIndices.Count == 0) 
     listViewToMunge.SelectedIndices.Add(this.lastSelectedIndex); 
} 

private bool appIdleEventScheduled = false; 
private int lastSelectedIndex = -1; 
private ListView listViewToMunge; 
2

he logrado de esta manera:

private void lvReads_MouseUp(object sender, MouseEventArgs e) 
    { 
     if (lvReads.SelectedItems.Count == 0) 
      if (lvReads.Items.Count > 0) 
       lvReads.Items.Find(currentName, false)[0].Selected = true; 
    } 

y

private void lvReads_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (lvReads.SelectedItems.Count == 1) 
     {    
      selectedIndex = lvReads.SelectedIndices[0]; 

      if (currentName != lvReads.Items[selectedIndex].Name) 
      { 

       //load item 
      } 

      currentName = lvReads.Items[selectedIndex].Name; 
     } 
    } 
+0

Esta es una solución efectiva con un código mínimo. – hfann

1

Usted tiene que heredar de la clase ListView y hacer algo de procesamiento de mensajes de bajo nivel

class ListViewThatKeepsSelection : ListView 
{ 
    protected override void WndProc(ref Message m) 
    { 
     // Suppress mouse messages that are OUTSIDE of the items area 
     if (m.Msg >= 0x201 && m.Msg <= 0x209) 
     { 
      Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16); 
      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); 
    } 
} 
+2

La misma respuesta aquí: http://stackoverflow.com/a/3255191/188926 – Dunc

7

El control de vista de lista tiene un HideSelection propiedad que por defecto es True. Hazlo False y estás listo para ir ... en algunos casos esto es suficiente.

+0

Esto no soluciona el problema publicado, no está teniendo problemas con los elementos que anulan la selección cuando pierde el foco. – Hugoagogo

+0

Corrección: * tiene un problema con la anulación de la selección de elementos.Los elementos seleccionados no se resaltan porque el control pierde qué elementos se seleccionan. – Suncat2000

Cuestiones relacionadas