This article is currently in the process of being translated into Hungarian (~95% done).
The ItemsControl
A WPF-ben számos eszköz áll rendelkezésünkre lista adatok megjelenítésére. Ezek eltérő kinézetűek, különböznek komplexitásban és abban, hogy mennyi munkát végeznek el nekünk. A legegyszerűbb közülük az ItemsControl, ami leginkább egy leíró ciklus - magunk kell elvégezzük az összes formázást, sablon beállításokat, de sok esetben csak ennyire van szükségünk.
Egy egyszerű ItemsControl példa
Kezdjük egy rendkívül egyszerű példával, ahol manuálisan töltjük fel az ItemsControl-t elemekkel. Ez a példa arra szolgál, hogy bemutassa mennyire egyszerű az ItemsControl.
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="ItemsControlSample" Height="150" Width="200">
<Grid Margin="10">
<ItemsControl>
<system:String>ItemsControl Item #1</system:String>
<system:String>ItemsControl Item #2</system:String>
<system:String>ItemsControl Item #3</system:String>
<system:String>ItemsControl Item #4</system:String>
<system:String>ItemsControl Item #5</system:String>
</ItemsControl>
</Grid>
</Window>
Láthatjuk, hogy semmi nem utal arra, hogy itt egy darab control-t használunk például 5 TextBlock control helyett - az ItemsControl-nak alapértelmezetten nincs egyedi kinézete. Semmi sem történik, ha rákattint valamelyik elemre, mert az ItemsControl nem rendelkezik SelecteItem vagy hasonló tulajdonságokkal.
ItemsControl adatkötéssel
Természetesen az ItemsControl nem arra készült, hogy csak előre definiált elemekkel használjuk, mint ahogyan az első példánkban tettük. Ahogyan a többi control is a WPF-ben, az ItemsControl is adat összerendelésre lett kitalálva, ahol sablonokat használunk, hogy meghatározzuk, hogy a mögöttes kódtartalom hogyan jelenjen meg a felhasználóknak.
Ezt demonstrálandó, összeraktam egy példát, ami egy "tennivalók" listát jelenít meg a felhasználónak, és hogy megmutassam, mennyire rugalmassá válik minden, miután elkészítettük a sablonunkat, egy Progressbar control-on keresztül megjelenítem a jelenlegi készültségi szintet. Jöjjön a kód, képernyőmentés, majd a magyarázat:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlDataBindingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ItemsControlDataBindingSample" Height="150" Width="300">
<Grid Margin="10">
<ItemsControl Name="icTodoList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}" />
<ProgressBar Grid.Column="1" Minimum="0" Maximum="100" Value="{Binding Completion}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
using System;
using System.Windows;
using System.Collections.Generic;
namespace WpfTutorialSamples.ItemsControl
{
public partial class ItemsControlDataBindingSample : Window
{
public ItemsControlDataBindingSample()
{
InitializeComponent();
List<TodoItem> items = new List<TodoItem>();
items.Add(new TodoItem() { Title = "Complete this WPF tutorial", Completion = 45 });
items.Add(new TodoItem() { Title = "Learn C#", Completion = 80 });
items.Add(new TodoItem() { Title = "Wash the car", Completion = 0 });
icTodoList.ItemsSource = items;
}
}
public class TodoItem
{
public string Title { get; set; }
public int Completion { get; set; }
}
}
A legfontosabb része a példaprogramnak az ItemsControl, azon belül az ItemsControl.ItemTemplate-en belül lévő DataTemplate-ben megírt sablon. Létrehoztunk egy Grid panel-t, benne 2 oszloppal: az elsőben egy TextBlock ami a "tennivalók" elem nevét jeleníti meg, a második oszlopba kerül a ProgressBar control, aminek értékét a Completition tulajdonsággal kötöttük össze.
A sablonunk most egy TodoItem-et képvisel, amit a mögöttes kód fájlban deklarálunk. Példánkban többet is megadunk és hozzáadjuk őket egy listához (items). Végül ezt a listát hozzárendeljük az ItemsControl-unk ItemsSource tulajdonságához, innentől ez a munka többi részét elvégzi nekünk. A sablonunk segítségével a lista minden eleme megjelenítődik, ahogy a képernyőmentésen is látható.
Az ItemsPanelTemplate tulajdonság
A fenti példában elem fentről lefelé rendezve jelenik meg, és minden elem egy teljes sort foglal el. Azért történik így, mert az ItemsControl alapértelmezetten egy függőlegesen igazított StackPanel-be rakja bele az összes elemet. Ezen könnyen változtathatunk, mivel az ItemsControl lehetőséget nyújt arra, hogy megváltoztassuk, hogy milyen panel típusba kerüljenek az elemeink. Itt egy példa:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlPanelSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="ItemsControlPanelSample" Height="150" Width="250">
<Grid Margin="10">
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}" Margin="0,0,5,5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<system:String>Item #1</system:String>
<system:String>Item #2</system:String>
<system:String>Item #3</system:String>
<system:String>Item #4</system:String>
<system:String>Item #5</system:String>
</ItemsControl>
</Grid>
</Window>
Meghatározzuk, hogy az ItemsControl WrapPanel panel típust használjon úgy, hogy deklaráljuk a ItemsPanelTemplate tulajdonságon belül. A poén kedvéért hozzáadunk egy ItemTemplate-et, aminek hatására a string-ek button-ként fognak megjelenni. Bármelyik WPF panel-t használhatjuk, de egyesek jóval használhatóbbak, mint mások.
Another good example is the UniformGrid panel, where we can define a number of columns and then have our items neatly shown in equally-wide columns:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlPanelSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="ItemsControlPanelSample" Height="150" Width="250">
<Grid Margin="10">
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}" Margin="0,0,5,5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<system:String>Item #1</system:String>
<system:String>Item #2</system:String>
<system:String>Item #3</system:String>
<system:String>Item #4</system:String>
<system:String>Item #5</system:String>
</ItemsControl>
</Grid>
</Window>
ItemsControl gördülő sávval
Ahogy elkezdjük használni az ItemsControl-t, könnyen belefuthatunk egy gyakori problémába: alapértelmezetten az ItemsControl nem rendelkezik gördülő sávval, ami azt jelenti, hogy, ha a tartalmunk nem fér bele, akkor egyszerűen levágja azt. A jelenség megfigyelhető, ha az első példaprogramunkban átméretezzük az ablakot:
A WPF-ben egyszerűen tudjuk ezt orvosolni. Több megoldási lehetőségünk is van, például megváltoztathatjuk az ItemsControl által használt sablont, hogy tartalmazzon egy ScrollViewer control-t, de a legegyszerűbb megoldás, hogy az ItemsControl "köré" írjuk a ScrollViewer-t. Itt egy példa:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="ItemsControlSample" Height="150" Width="200">
<Grid Margin="10">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ItemsControl>
<system:String>ItemsControl Item #1</system:String>
<system:String>ItemsControl Item #2</system:String>
<system:String>ItemsControl Item #3</system:String>
<system:String>ItemsControl Item #4</system:String>
<system:String>ItemsControl Item #5</system:String>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
A két láthatósági lehetőséget Auto-ra állítotam, hogy csak akkor legyenek láthatók, amikor szükséges. Most már végiggörgethetünk a listánk összes elemén, ahogy az a képernyőmentésen is látható.
Summary
Az ItemsControl remek megoldás, ha szabad kezet akarunk abban, hogy hogyan jelenjenek meg az adataink és mellette nincs szükség arra, hogy ezek kiválaszthatók legyenek. Ha azt szeretnénk, hogy a felhasználók ki tudjanak választani elemeket a listából, akkor másik control-t kell használnunk, pl.: ListBox vagy ListView. Ezek a következő fejezetekben kerülnek bemutatásra.