2012-03-05 29 views
9

Nie mogłem znaleźć żadnych uwag na temat MSDN ListView.Groups Property, że pusta ListViewGroup będzie ukryta. Czy to projekt, czy coś mi brakuje? Mój przykładowy kod pokaże tylko "grupa 2" z pozycją "przedmiot1".Pusta ListViewGroup nie jest wyświetlana w 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 

Aktualizacja: Czy istnieje jakiś sposób, aby pokazać ListViewGroup bez dodawania atrapę element

Na razie tylko obejście pomysł mam jest użycie collapsible listview (Vista i nowsze)

+0

miarę Wiem, puste grupy po prostu nie są wyświetlane. Możesz dodać pusty element, aby wyświetlić grupę. – nik

+0

Myślę, że masz odpowiedź: –

+0

Prawidłowo. Puste grupy nie wyświetlają się. Najpierw musisz dodać elementy do nich. –

Odpowiedz

3

nie jest możliwe według projektu Microsoft.
Spójrz na tę dyskusję pod numerem social.msdn.microsoft.com.
Nie daj się zwieść tytułem. Mówi o pustych grupach.

+0

To prawda. Patrząc na kod źródłowy ListView, całe malowanie i grupowanie odbywa się za pomocą PInvokes, co oznacza, że ​​nie jest to zwykła sprawa nadpisania metody rysowania ListView. Może być sposób, w jaki możesz to zrobić za pomocą małego "hacka", który zamieszczę, ale nie jest ładny. – SPFiredrake

+1

W tym przypadku wspieram decyzję projektową firmy Microsoft. Nie lubię otwierać grupy i niczego nie znajduję w środku. Lepiej nie pokazywać niczego. – Steve

1

Hak, o którym mówię powyżej, NIE JEST ZALECANY. Jeśli jednak NAPRAWDĘ chcesz, aby pojawiły się puste grupy, wystarczy przekazać kod dodawania do oddzielnej metody narzędzia, która sprawdza, czy grupa jest pusta. Jeśli tak, dodaje go do "domyślnej" grupy (więc przynajmniej się pojawia), dopóki nie dodasz do niej elementu.

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); 
} 

Kolejne ostrzeżenie, NIEZALECANE. Jest to dość spore obciążenie i naprawdę nie warte problemów (IMO). Ale hej, do każdego z nich. Ten kod jest całkowicie nieprzetestowany i po prostu go wyrzucamy, jeśli naprawdę POTRZEBUJESZ tego działania (co nigdy nie powinno mieć miejsca, lepiej szukać alternatyw). Najgorsze jest to, że deklaracja grupy znajduje się w samym Listitem, dzięki czemu można łatwo zmienić grupę.

Ostatnie ostrzeżenie, NIEZALECANE.

Edytuj: Zmodyfikowałem powyższy kod, aby był metodami rozszerzenia obiektów ListView, dzięki czemu masz bezpośredni dostęp do ListView z metod. Za każdym razem, gdy dodajesz grupę, możesz po prostu zadzwonić pod numer listView.AddGroup, dodając element, który możesz wykorzystać w metodach listView.AddItem. Jest to sprzeczne z metodami listView.Items.Add i listView.Groups.Add. Należy pamiętać o tym, że nie trzeba przypisywać elementów do grup, a jedynie przypisywać grupy do elementów. Dzięki temu można przełączać elementy między grupami, zmieniając odniesienie, zamiast usuwać/dodawać odwołania między grupami. Zakłada to również, że zadeklarowałeś, że Header z ListItemGroup jest taki sam jak Key (innymi słowy, new ListItemGroup("HeaderText" /*KEY*/, "HeaderText" /*HEADER*/). W przeciwnym razie wystarczy zmienić logikę w obrębie AddItem, aby odnieść się do właściwej wartości (co oznacza Name, zwykle).)

+0

w jaki sposób można użyć tego kodu, czy masz próbkę? – walter

0

"Wcześniej w tym roku wpadłem na ten sam problem, rozważając wyświetlanie pustych grup." Microsoft, według projektu, nie wyświetla nazwy grupy, która jest pusta od jakichkolwiek elementów. utwórz/dodaj pusty element lub element z pustym tekstem do grupy.Jeśli masz faktyczne elementy danych do wypełnienia dla tej grupy, musisz pamiętać, aby usunąć pusty/pusty element z tej grupy. "

Źródło: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/39681a70-d992-4046-ad7e-21a2e33791b1

4

Better ListView może zrobić dokładnie to.Jest ShowEmptyGroups właściwość, która załatwia sprawę:

empty group in Better ListView

Istnieje również Lepsze ListView ekspresowe, który jest darmowy i obsługuje grup. To nie jest opakowaniem ListView, ale kompletna re-implementacja wszystkich funkcji, 100% udało i po prostu się ... lepiej :-)

+0

+1 wygląda ładnie, próbowałem Better ListView Express – walter

3

ta metoda sprawia czy ListViewGroup pokazuje

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(); 
       } 
      } 
     } 
    } 
} 
Powiązane problemy