2012-03-05 29 views
9

no pude encontrar ninguna observación en MSDN ListView.Groups Property que se ocultará ListViewGroup vacía. ¿Es por diseño o me falta algo? Mi código de muestra a continuación solo mostrará el "grupo 2" con el elemento "elemento1".ListViewGroup vacío no se muestra en ListView

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ 
     Handles MyBase.Load 
    ' 
    Dim gr = New ListViewGroup("group 1") 
    ListView1.Groups.Add(gr) 
    ' 
    Dim gr2 = New ListViewGroup("group 2") 
    ListView1.Groups.Add(gr2) 
    ' 
    Dim lvi As New ListViewItem("item1") 
    ListView1.Items.Add(lvi) 
    ' 
    gr2.Items.Add(lvi) 
End Sub 

Actualizado: es que hay alguna manera de mostrar ListViewGroup sin añadir elemento ficticio

Por ahora la única idea de solución que tengo es usar collapsible listview (Vista y hacia arriba)

+0

Por lo Lo sé, los grupos vacíos simplemente no se muestran. Puede agregar un elemento de cadena en blanco solo para mostrar el grupo. – nik

+0

Creo que recibiste tu respuesta –

+0

Correcto. Los grupos vacíos no aparecen. Primero debe agregar elementos a ellos. –

Respuesta

3

no es posible por el diseño de Microsoft.
Consulte esta discusión en social.msdn.microsoft.com.
No se deje engañar por el título. Habla de grupos vacíos.

+0

Eso es correcto. Al observar el código fuente de ListView, toda la pintura y la agrupación se realiza a través de PInvokes, lo que significa que no se trata simplemente de anular el método de dibujo de ListView. Puede haber una manera de hacerlo mediante el uso de un pequeño "truco" que publicaré, pero no es bonito. – SPFiredrake

+1

En este caso, apoyo la decisión de diseño de Microsoft. No me gusta abrir un grupo y no encontrar nada dentro. Mejor no mostrar nada. – Steve

1

El truco que estoy hablando por encima no se recomienda. Sin embargo, si REALMENTE desea que aparezcan grupos vacíos, entonces simplemente delegaría el código de adición a un método de utilidad separado que verifica si el grupo está vacío. Si es así, lo agrega al grupo "predeterminado" (por lo que aparece al menos) hasta que agrega un elemento.

public static void AddGroup(this ListView lv, ListViewGroup lg) 
{ 
    if (lg.Items.Count > 0 || lv.Items.Cast<ListViewItem>().Any(tg => tg.Group == lg)) 
     lv.Groups.Add(lg); 
    else 
    { 
     var item = lv.Items.Add(lg.Header); 
     item.Tag = lg; 
    } 
} 

public static void AddItem(this ListView lv, ListViewItem li, string groupKey) // Could also take ListViewGroup here... 
{ 
    if (lv.Groups[groupKey] == null && lv.Items.ContainsKey(groupKey)) 
    { 
     lv.Groups.Add((ListViewGroup)lv.Items[groupKey].Tag); 
     lv.Items.RemoveByKey(groupKey); 
    } 
    lv.Items.Add(li); 
    li.Group = lv.Groups[groupKey]; 
} 

public static void AddItem(this ListView lv, ListViewItem li, ListViewGroup lg) 
{ 
    lv.AddItem(li, lg.Header); 
} 

Otra advertencia, NO SE RECOMIENDA. Esto es bastante elevado, y realmente no vale la pena (IMO). Pero bueno, a cada uno lo suyo. Este código no se ha probado completamente, y simplemente lo arroja allí en caso de que realmente NECESITE que esto funcione (lo que nunca debería ser el caso, mejor buscar alternativas). La peor parte es que la declaración del Grupo simplemente reside en el ListItem mismo, de esa manera puede simplemente cambiar el grupo con bastante facilidad.

Última advertencia, no se recomienda.

Edición: He modificado el código anterior para ser métodos de extensión en los objetos ListView, de esa manera se tiene acceso directo a la ListView de los métodos. Cada vez que se agrega un grupo, usted acaba de llamar listView.AddGroup, añadiendo un elemento que puede utilizar los métodos de listView.AddItem. Esto se opone a los métodos listView.Items.Add y listView.Groups.Add. Lo único a tener en cuenta es que no necesita asignar elementos a los grupos, sino que solo asigna los grupos a los elementos. Esto hace que pueda cambiar elementos entre grupos cambiando la referencia, en lugar de tener que eliminar/agregar referencias entre grupos. Esto también asume que ha declarado que el Header del ListItemGroup es el mismo que el Key (en otras palabras, new ListItemGroup("HeaderText" /*KEY*/, "HeaderText" /*HEADER*/). De lo contrario, solo tiene que cambiar la lógica dentro de AddItem para hacer referencia al valor correcto (que es Name, por lo general)

+0

cómo se puede usar este código, ¿tiene una muestra? – walter

0

"Me encontré con el mismo problema a principios de este año al considerar la visualización de grupos vacíos. Microsoft, por diseño, no muestra un nombre de grupo que está vacío de cualquier elemento. Lo que tienes que hacer es crear/añadir un elemento vacío o un elemento que sostiene un carácter en blanco de texto para el grupo. Cuando se tiene dato real (s) para poblar para ese grupo, entonces debe recordar para eliminar el elemento vacío/en blanco de ese grupo."

Fuente: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/39681a70-d992-4046-ad7e-21a2e33791b1

4

Better ListView puede hacer exactamente esto.Hay un ShowEmptyGroups propiedad que hace el truco:

empty group in Better ListView

También hay un Mejor ListView expreso, que es gratuito y es compatible con los grupos también. No es un envoltorio ListView, pero una completa re-aplicación de todas las características, el 100% gestionado y acaba de hacer mejor ... :-)

+0

+1 se ve bien, lo he intentado con Better ListView Express – walter

3

este método se asegura la ListViewGroup muestra

void MakeSureListViewGroupHeaderShows(ListView lv) 
{ 
    foreach (ListViewGroup lvg in lv.Groups) 
    { 
     if (lvg.Items.Count == 0) 
     { 
      // add empty list view item 
      ListViewItem lvi = new ListViewItem(string.Empty); 
      lvi.Group = lvg; 
      lv.Items.Add(lvi); 
     } 
     else 
     { 
      // remove our dummy list view item 
      foreach (ListViewItem lvi in lvg.Items) 
      { 
       if (lvi.Text == string.Empty) 
       { 
        lvi.Remove(); 
       } 
      } 
     } 
    } 
} 
Cuestiones relacionadas