This article has been localized into Czech by the community.
Seskupování dat v ListView
Jak jsme si již řekli dříve, WPF ListView je velmi flexibilní prvek. Seskupování je další věcí, kterou podporuje samo o sobě tak jak je, a také můžete tuto vlastnosti snadno použití a přizpůsobit. Ukažme si to přímo na prvním příkladu, pak to všechno vysvětlím a následně již budete sami schopni používat standardní triky WPF a přizpůsobovat vzhled podle potřeby.
Pro tento článek jsem si vypůjčil ukázkový kód z předchozího článku a pak jej rozšířil o schopnost podpory seskupení. Vypadá to takto:
<Window x:Class="WpfTutorialSamples.ListView_control.ListViewGroupSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ListViewGroupSample" Height="300" Width="300">
<Grid Margin="10">
<ListView Name="lvUsers">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="14" Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;
namespace WpfTutorialSamples.ListView_control
{
public partial class ListViewGroupSample : Window
{
public ListViewGroupSample()
{
InitializeComponent();
List<User> items = new List<User>();
items.Add(new User() { Name = "John Doe", Age = 42, Sex = SexType.Male });
items.Add(new User() { Name = "Jane Doe", Age = 39, Sex = SexType.Female });
items.Add(new User() { Name = "Sammy Doe", Age = 13, Sex = SexType.Male });
lvUsers.ItemsSource = items;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("Sex");
view.GroupDescriptions.Add(groupDescription);
}
}
public enum SexType { Male, Female };
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Mail { get; set; }
public SexType Sex { get; set; }
}
}
V XAML kódu jsem přidal do ListView značku GroupStyle, ve které definuji šablonu pro záhlaví každé skupiny. Skládá se z ovládacího prvku TextBlock, kde jsem použil o něco větší a tučný text, abych skupinu zvýraznil, a jak uvidíme později, můžeme toho přizpůsobit mnohem více. Vlastnost TextBlock Text je vázána na vlastnost Name, ale uvědomte si, že se nejedná o vlastnost Name na datovém objektu (v tomto případě třídu User). Místo toho je to název skupiny, přiřazené ve WPF, a to na základě vlastnosti, kterou používáme k rozdělení objektů do skupin.
V Code-behind, provedeme totéž, co jsme udělali předtím: Vytvoříme seznam, přidáme některé objekty User a k němu a pak navážeme seznam listView, tedy nic nového na tom není, s výjimkou nové vlastnosti Sex, kterou jsem přidal, k rozlišení, zda uživatel je muž nebo žena.
Přiřazením ItemsSource, v CollectionView, pro nás ListView vytvoří požadované zobrazení dat. Tato instance specializovaného zobrazení - View obsahuje mnoho různých možností zobrazení dat, včetně možnosti seskupování položek. Toho docílíme tak, že vytvoříme instanci prvku zobrazení PropertyGroupDescription – groupDescription s parametrem některé vlastnosti vázaných dat. To v podstatě říká WPF aby seskupilo data podle určité vlastnosti datového objektu, v tomto případě vlastnosti Sex.
Přizpůsobení záhlaví skupiny
Výše uvedený příklad je výbornou ukázkou zobrazení základů při seskupování dat v ListView, ale vzhled zobrazovaných dat je přece jen trochu nudný, takže využijme skutečnosti, že WPF nám umožňuje definovat vlastní šablony a zobrazení tak trochu lépe „okořenit“. Běžným požadavkem je možnost sbalit a rozbalit skupinu, a i když to ve výchozím nastavení WPF neumožňuje, můžeme toto chování poměrně snadno implementovat sami. Uděláme to tak, že kompletně upravíme styl skupinového kontejneru.
Může to vypadat trochu těžkopádně, ale použité principy jsou docela jednoduché a při přizpůsobování ovládacích prvků WPF je můžete vidět a použít také v jiných situacích. Zde je kód:
<Window x:Class="WpfTutorialSamples.ListView_control.ListViewCollapseExpandGroupSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ListViewCollapseExpandGroupSample" Height="300" Width="300">
<Grid Margin="10">
<ListView Name="lvUsers">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ItemCount}" FontSize="22" Foreground="Green" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" item(s)" FontSize="22" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
</Window>
Code-behind je přesně stejné jako v prvním příkladu – takže si data zkuste sbalit a rozbalit.
Nyní naše skupiny vypadají trochu více sexy, a dokonce obsahují expanzní tlačítko, na které když kliknete, přepínají viditelnost skupin položek (to je důvod, proč není na snímku obrazovky viditelný žádná položka dat ve spodní skupině – tato konkrétní skupina je sbalena). Pomocí vlastnosti ItemCount, kterou daní skupina zveřejňuje, můžeme dokonce zobrazit, i z kolika položek se daná skupina aktuálně skládá.
Jak můžete vidět, vyžaduje to trochu více značek, než jsme zvyklí, ale tento příklad také jde trochu nad rámec toho, co obvykle děláme, takže se mi to zdá spravedlivé. Při čtení kódu si rychle uvědomíte, že mnoho řádků jsou jen běžné prvky, jako je styl a šablona.
Shrnutí
Přidání možnosti seskupování dat do WPF ListView je velmi jednoduché. Vše, co potřebujete, je GroupStyle s HeaderTemplate, abyste sdělili ListView, jak vykreslit skupinu a dále několik řádků kódu Code-behind které řeknou WPF, podle které vlastnosti data seskupit. Jak můžete vidět z posledního příkladu, skupina je dokonce velmi přizpůsobitelná, což vám umožní bez velké námahy vytvořit některé opravdu skvělé pohledy.