Doteď jsme používali pro zobrazování dat DataGrid. Co když si ale budeme se vzhledem výpisu trochu pohrát? Tento díl bude hlavně o možnostech ListBoxu v Silverlightu.
Jak už jste mohli pochopit z úvodu, dnes jako první odstraníme dosavadní DataGrid a nahradíme ho ListBoxem, jméno StoriesList mu necháme. Odpovídající část XAMLu bude vypadat takto:
<ListBox x:Name="StoriesList" Grid.Row="1" />
Když teď aplikaci spustíme, dostaneme ne zrovna uspokojivý výsledek:
Ale proč se zobrazuje text „DiggSample.DiggStory“? Důvod je ten, že máme na ListBox navázané přímo DiggStory objekty a tohle dostaneme, když na ně zavoláme metodu ToString. Pokud bychom chtěli zobrazit hodnotu vlastnosti Title, museli bychom ListBoxu patřičně nastavit vlastnost DisplayMemberPath:
<ListBox x:Name="StoriesList" Grid.Row="1" DisplayMemberPath="Title" />
Teď už to bude mnohem lepší:
Pokud bychom chtěli zobrazit na jednom řádku víc než jen jednu hodnotu, můžeme přepsat šablonu ItemTemplate a vytvořit upravenou DataTemplate. DataTemplate se pak bude chovat jako šablona, podle které se vykreslí každý z prvků ListBoxu. Například hodnoty Title a NumDiggs najednou zobrazíme následovně:
<ListBox x:Name="StoriesList" Grid.Row="1" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding NumDiggs}" Margin="5" Foreground="Red" />
<TextBlock Text="{Binding Title}" Margin="5" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Takhle můžeme postupovat se všemi vlastnostmi, ale zatím se spokojíme s tímto. Všimněte si {Binding Path} syntaxe, která se právě stará o navazování dat. Takže teď náš Digg klient vypadá jako na obrázku.
My ale půjdeme ještě dál a DataTemplate si upravíme tak, aby používala dva StackPanely – jeden zarovná objekty do řádku a druhý zajistí, aby byl počet „diggů“ vždy pod sebou. Následuje kód souboru Page.xaml a hned za ním pár nových stylů souboru App.xaml (staré tam ponechte):
<!-- Page.xaml-->
<ListBox x:Name="StoriesList" Grid.Row="1" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Style="{StaticResource DiggPanel}" >
<TextBlock Text="{Binding NumDiggs}" Style="{StaticResource NumDigsBlock}" />
<TextBlock Text="diggy" Style="{StaticResource NumDigsSubBlock}" />
</StackPanel>
<Image Source="{Binding ThumbNail}" Style="{StaticResource ThumbNailPreview}" />
<TextBlock Text="{Binding Title}" Margin="5" Style="{StaticResource TitleBlock}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- Nové styly v App.xaml-->
<Style x:Key="DiggPanel" TargetType="StackPanel">
<Setter Property="Margin" Value="10" />
<Setter Property="Width" Value="55" />
<Setter Property="Height" Value="55" />
<!-- Pozadí jako přechod (gradient) -->
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFF098" />
<GradientStop Color="#FFFFF9D4" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NumDigsBlock" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontSize" Value="18" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="DarkSlateGray" />
</Style>
<Style x:Key="NumDigsSubBlock" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Foreground" Value="DarkSlateGray" />
</Style>
<Style x:Key="ThumbNailPreview" TargetType="Image">
<Setter Property="Margin" Value="7,7,5,5" />
<Setter Property="Height" Value="55" />
</Style>
<Style x:Key="TitleBlock" TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Trebuchet MS" />
<Setter Property="TextAlignment" Value="Left" />
</Style>
A je to! Ovšem pozor na spouštění pomocí F5 přímo z Visual Studia, aplikace při načtení obrázků vyhodí chybu AG_E_NETWORK_ERROR se skutečně vyčerpávajícím popisem:
Error: Unhandled Error in Silverlight 2 Application SilverlightApp.xap Code: 4001 Category: MediaError Message: AG_E_NETWORK_ERROR
Musím se přiznat, že se mi nepovedlo úplně zjistit, čím je tato chyba způsobena. Všude říkají něco jiného, ale nic nepasuje přímo na tuto aplikaci. V článcích Scotta Guthrieho, jejichž českou verzi právě čtete, o tom taky není zmínka, asi to v některé betaverzi Silverlightu fungovalo dobře. Zvláštní. V každém případě, pokud aplikaci spustíte přes IIS na localhostu (stačí jednoduše zkopírovat složku s projektem do adresáře C:inetpubwwwroot) nebo ji dáte na web, vše bude fungovat jak má.
Ještě než si ukážeme obrázek, jak to teď vypadá, tak vás vyzvu, abyste si všimli toho, že i když jsme změnili datovou šablonu ListBoxu, všechny jeho animace pro kliknutí, přejetí myši, atd., pořád zůstávají. Pokud zmenšíte okno prohlížeče, v ListBoxu se automaticky objeví posuvníky, které vám umožní přesouvat se po jeho obsahu. Však si to můžete zkusit sami a teď už konečně obrázek:
Příště nás čeká vytvoření vyskakovacího okénka s detaily o „diggu“, které jste měli možnost vidět v úvodním díle.