Silverlight 3.0 : Objekty pre vytvorenie prezentačnej vrstvy
Po pokusoch s obdĺžnikom v úvodnom príklade nastal čas na podrobnejšie zoznámenie sa s hierarchiou objektov pre tvorbu prezentačnej vrstvy a používateľského rozhrania.
Kontajnery na zapuzdrovanie prvkov
Na zapuzdrovanie prvkov sa využívajú kontajnerové objekty:
- Grid,
- Canvas,
- Stack Panel.
Tieto objekty zapuzdrujú prvky nielen z pohľadu objektovo orientovaného programovania ale aj doslova vizuálne, to znamená, že napríklad udržiavajú ich absolútnu aj relatívnu polohu aj pri zmene rozmerov okna.
Objekt Grid
Znovu pripomenieme XAML kód prázdnej stránky vygenerovanej sprievodcom:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SL3app.MainPage"
Width="640" Height="480">
<Grid x:Name="LayoutRoot" Background="White"/>
</UserControl>
Už táto kostra stránky obsahuje kontajnerový prvok Grid. Prečo?
Určite ste si všimli, že väčšina webových aplikácií má pracovnú plochu rozvrhnutú na niekoľko samostatných oblastí. Môže to byť realizované napríklad pomocou HTML tabuľky. Táto tabuľka vlastne udržiava prvky v nej na absolútnych, alebo relatívnych pozíciách.
Ak v prostredí Expression Blend 3 kliknete na malý štvorček v pravom hornom rohu orámovania bielej návrhovej plochy, môžete pomocou posúvania a umiestňovania pravítok rozdeliť pracovnú plochu na niekoľko oblastí a to vodorovne alebo zvisle.
Ukážeme príklad tabuľky, so záhlavím a riadkami, aké sa často používajú na webových stránkach. Všimnite si, že rozmery, ktoré sa budú prispôsobovať napríklad veľkosti stránky sú definované pomocou znaku „*“ (hviezdička).
Interaktívny návrh mriežky tabuľky
V našom prípade bol výsledkom vizuálneho návrhu kód:
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="0.117*"/>
<RowDefinition Height="0.36*"/>
<RowDefinition Height="0.523*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.158*"/>
<ColumnDefinition Width="0.842*"/>
</Grid.ColumnDefinitions>
</Grid>
Prepínaním ikony v ľavom hornom rohu sa dá meniť absolútne a relatívne rozmiestnenie buniek. Pomocou ikon visacích zámkov môžete „zamknúť“ fixné nastavenie rozmerov vybranej oblasti, je potrebné nastaviť parameter ShowGridLines="true". Pri absolútnom rozmiestnení prvý riadok napríklad <RowDefinition Height="10"/> alebo prvý stĺpec napríklad <ColumnDefinition Width="10"/> udávajú okraj.
Objekt Canvas
Silverlight aplikácie využívajú objektový model pracovnej plochy s názvom Canvas. Preklad tohto pojmu do slovenčiny je pomerne výstižný, je to virtuálne maliarske, prípadne premietacie plátno, ktoré reprezentuje viditeľnú prezentačnú vrstvu Silverlight aplikácie. Na túto plochu sa potom umiestňujú grafické objekty. Pri grafických objektoch môžete stanoviť ich polohu. Vo fragmente kódu je definícia polohy tlačidla voči ploche Canvas:
<Canvas Height="150" Margin="150,70,260,0" VerticalAlignment="Top">
<Button Canvas.Left="20" Canvas.Top="20" Content="O.K." ></Button>
</Canvas>
Relatívna poloha plochy geometrického obrazca voči ploche Canvas
Všimnite si aj v kóde aj na obrázku, že poloha objektu Canvas je vymedzená voči kontejneru Grid, že
XAML aplikácia môže obsahovať viac plôch „Canvas“, pričom tieto môžu byť rôzne vnorené. V príklade je vo vnútri hlavnej (bielej) plochy vnorená ďalšia, červená vnorená plocha Canvas. Vo vnútri vnorenej plochy je zobrazená geometrická plocha (elipsa), pričom poloha elipsy je zadaná ako relatívna voči vnútornej vnorenej ploche „Canvas“:
<Canvas Background="White">
<Canvas Background="Red" Canvas.Top="25" Canvas.Left="25"
Width="250" Height="100">
<Ellipse Canvas.Top="10" Canvas.Left="25"
Width="150" Height="75" Fill="Yellow" />
</Canvas>
</Canvas>
Vnorenie objektov Canvas
Objekt Stack Panel
Objekt Stack Panel slúži na rozmiestnenie objektov nad sebou, alebo vedľa seba. Implicitná orientácia usporiadania je vertikálna. Príklad ukazuje umiestnenie troch tlačidiel:
<StackPanel Background="Yellow">
<Button Content="Moznost 1" Width="80" Margin="10"/>
<Button Content="Moznost 2" Width="80" Margin="10"/>
<Button Content="Moznost 3" Width="80" Margin="10"/>
</StackPanel>
Usporiadanie objektov pomocou Stack Panelu
Ak zmeníte orientáciu na horizontálnu, zmení sa usporiadanie objektov zapuzdrených v Stack Paneli.
Široká ponuka komponentov
Silverlight 3 obsahuje viac než 60 prispôsobiteľných ovládacích prvkov typu „out-of-the-box “. Náhodne spomenieme nové prvky, napríklad ChildWindow, TreeView a DataGrid.
Dialógové okno
Jedným z prvkov stierania rozdielu medzi klasickými a webovými aplikáciami s interaktívnym používateľským rozhraním je aj dialógové okno, ktoré určite dôverne poznáte z klasických aplikácií.
Pridanie novej entity, v tomto prípade ChildWindow
Do projektu bude pridaná šablóna okna obsahujúca dve tlačidlá:
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="Text oznamu"></TextBlock>
<Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75"
Height="23" HorizontalAlignment="Right" Grid.Row="1" />
<Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click"
Width="75" Height="23" HorizontalAlignment="Right" Margin="0,0,79,0"
Grid.Row="1" />
</Grid>
Pripravené sú aj šablóny obslužného kódu tlačidiel:
private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
Z hlavnej stránky môžete dialógové okno aktivovať napríklad tlačidlom s obslužným kódom:
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
ChildWindow1 dlg = new ChildWindow1();
dlg.Show();
}
Aplikácia využívajúca ChildWindow
TreeView pre zobrazenie hierarchickej štruktúry
Aplikácie nadväzujú na procesy a organizačné štruktúry z reálneho sveta. Jedný m z aspektov reálneho života – o podnikovom prostredí ani nehovoriac – je hierarchická štruktúra. Hierarchicky sú zoradené organizačné zložky, zamestnanci do kategórií a podkategórií sú rozdelené produkty. Jednou z možností pre zobrazenie hierarchických štruktúr v Silverlight aplikáciách je objekt TreeView. Všimnite si, že do záhlavia XAML dokumentu bol pridaný namespace System.Windows.Controls:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
x:Class="SILprvky.MainPage"
Width="640" Height="480">
<Grid x:Name="LayoutRoot" Background="White">
<controls:TreeView>
<controls:TreeViewItem Header="Najvyssia uroven hierarchie.">
<controls:TreeViewItem.Items>
<controls:TreeViewItem>
<controls:TreeViewItem.Header>
<TextBlock Text="Polozka 1" Margin="2"/>
</controls:TreeViewItem.Header>
</controls:TreeViewItem>
<controls:TreeViewItem>
<controls:TreeViewItem.Header>
<TextBlock Text="Polozka 2" Margin="2"/>
</controls:TreeViewItem.Header>
</controls:TreeViewItem>
</controls:TreeViewItem.Items>
</controls:TreeViewItem>
</controls:TreeView>
</Grid>
</UserControl>
Aplikácia využívajúca TreeView
DataGrid
Pre komfortné a interaktívne zobrazenie záznamov, či už z relačných databáz, XML súborov, alebo údajov zapuzdrených v objektoch je určený prvok DataGrid. Tento prvok podporuje aj zobrazovanie hierarchickej štruktúry údajov. V príklade budú údaje poskytnuté triedou Customer, ktorá obsahuje údaje o zákazníkoch.
XAML kód:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Controls;
assembly=System.Windows.Controls.Data" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="SILprvky.MainPage"
Width="640" Height="480" mc:Ignorable="d">
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid x:Name="dataGrid1"
Margin="31,24,45,225"
RowDetailsVisibilityMode="VisibleWhenSelected"
d:LayoutOverrides="VerticalAlignment" >
<data:DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="12" Text="Addresy: " />
<TextBlock FontSize="12" Text="{Binding Address}"/>
</StackPanel>
</DataTemplate>
</data:DataGrid.RowDetailsTemplate>
</data:DataGrid>
</Grid>
</UserControl>
Údaje budú poskytnuté triedou Customer:
using System.Collections.Generic;
namespace SILprvky
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
dataGrid1.ItemsSource = Customer.GetSampleCustomerList();
}
}
public class Customer
{
public String FirstName { get; set; }
public String LastName { get; set; }
public String Address { get; set; }
public Customer(String firstName, String lastName, String address)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Address = address;
}
public static List GetSampleCustomerList()
{
return new List(new Customer[3]
{
new Customer("Jan", "Novak",
"Slnecna 54 Prievidza"),
new Customer("Zuzana", "Ticha",
"Komjatna 1367"),
new Customer("Emil", "Skokan",
"Krizna 33 Bratislava"),
});
}
}
Aplikácia využívajúca DataGrid
Zviazanie elementov (databinding)
Na platforme Silverlight 3 je možné nielen napojiť elementy na zdroj údajov, ale prostredníctvom databindingu ich prepojiť navzájom. Logicky vzaté, má zmysel prepojiť prvok, ktorý generuje údaje na prvok, ktorý údaje „konzumuje“, teda sa podľa nich správa. V príklade bude takýmto prvkom geometrický obrazec – elipsa, ktorá bude mať parameter, dĺžku jednej zo svojich osí, naviazaný na prvok, pomocou ktorého bude možné meniť hodnoty tohto parametra:
<Grid x:Name="LayoutRoot" Background="White">
<Slider Width="400" Minimum="0" Maximum="400" Value="200" x:Name="reg"/>
<Ellipse Height="100" Fill="Blue" Width="{Binding ElementName=reg, Path=Value}"
Margin ="200,75,224,0" VerticalAlignment="Top" d:LayoutOverrides="Height"/>
</Grid>
Zviazanie elementov
Väzba medzi prvkami je v tomto prípade jednosmerná, teda Slider ovplyvňuje grafický prvok – elipsu. Opačná väzba nie je definovaná, nakoniec nie je ani logická, nakoľko elipsa je pasívny grafický prvok. Ako ďalší námet pre zviazanie elementov si môžete vyskúšať zviazanie prvku Slider s prvkom TextBlock, v ktorom sa bude zobrazovať hodnota nastavená pomocou prvku.
Validácia údajov
Na formuláre v interaktívnych webových aplikáciách sú kladené určité požiadavky, hlavne vzhľadom na komfort používateľov. Hlavne v aplikáciách kde „ide o biznis“ je dôležité, aby údaje zadané používateľom (údaje, rodné číslo, číslo objednávky, číslo kreditnej karty...) boli zadané úplne presne a správne. Od bežného klienta, napríklad návštevníka internetového obchodu, samozrejme nemôžete chcieť, aby poznal všetky detaily vašej aplikácie. Pre vývojára je „samozrejmé“, že sa bude používať desatinná bodka, matematicky „odchovaný“ klient neprogramátor tam celkom pochopiteľne zadá čiarku, problémy sú zo zadávaním formátu dátumu a času a podobne. Preto musíte používateľovi pomôcť nielen vhodným a jednoznačným návrhom formulára pre zadávanie údajov, ale aj zadávané údaje kontrolovať a používateľa usmerňovať tak, aby výsledkom jeho snaženia bola úspešná transakcia.
V príklade bude ukázaný formulár pre zadanie dvoch údajov – mena a osobného čísla:
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBox Margin="15" Width="200" Text="{Binding Meno,Mode=TwoWay,ValidatesOnExceptions=True}" />
<TextBox Margin="15" Width="200" Text="{Binding OsCislo,Mode=TwoWay,ValidatesOnExceptions=True}"/>
<ListBox x:Name="lstErrors" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Exception.Message}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Width="200" Content="Potvrd" Click="Button_Click" />
</StackPanel>
V prípade mena sa bude kontrolovať, či bol tento údaj zadaný v požadovanej minimálnej a maximálnej dĺžke reťazca, v prípade osobného čísla sa kontroluje, či je osobné číslo v požadovanom intervale hodnôt:
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace SL3new
{
public partial class MainControl : UserControl
{
public MainControl()
{
// Required to initialize variables
InitializeComponent();
this.Loaded += OnLoaded;
}
void OnLoaded(object sender, RoutedEventArgs e)
{
this.DataContext = new Pracovnik("Jozef Novak", 100);
lstErrors.DataContext = this;
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
List errors = new List();
foreach (UIElement ui in LayoutRoot.Children)
{
FrameworkElement fe = ui as FrameworkElement;
if (fe != null)
{
foreach (ValidationError ve in Validation.GetErrors(fe))
{
errors.Add(ve);
}
}
}
lstErrors.DataContext = errors;
}
}
public class InvalidDataException : Exception
{
public InvalidDataException(string msg) : base(msg)
{
}
}
Validované prvky sú napojené na objekt, v tomto prípade triedu Pracovník, kde sú zahrnuté aj validačné pravidlá:
public class Pracovnik
{
string meno;
int osCislo;
public Pracovnik(string meno, int osCislo)
{
this.meno = meno;
this.osCislo = osCislo;
}
public string Meno
{
get {return (meno);}
set {KontrolaDlzky(value, 3, 15); meno = value;}
}
public int OsCislo
{
get { return (osCislo); }
set
{
if ((value < 100) || (value > 199))
{
throw new InvalidDataException("Neplatne osobne cislo");
}
osCislo = value;
}
}
}

Validácia zadávaných údajov
Späť na obsah