WPF Value Converters, Styles, Triggers, DataTemplates, ControlTemplates - Luento 13
Selvitetään mitä ovat seuraavat asiat WPF:ssä: Value Converters, tyylit, Triggers, DataTemplatet, ControlTemplatet.
Luentoesimerkki (luento13_2012.zip
- Luentovideo (Youtube)
- tjlahton2012-02-29_1506.mp4 47.0 Mt
- tjlahton2012-02-29_1506.wmv 76.2 Mt
- tjlahton2012-02-29_1506.mp3 19.5 Mt
Value Converters
- Tietolähteitä sidottaessa pitää propertyjen tietotyyppien olla yhteensopivia
- Erilaisten tietotyyppien kohdalla yritetään tietotyypit automaattisesti muuntaa sopiviksi
- WPF sisältää valmiita konverttereita mutta omiakin pitää osata kirjoittaa
Peritään oma luokka IValueConverter-luokasta:
[ValueConversion(typeof(bool), typeof(Visibility))] public class BoolToVisibilityConverter : IValueConverter { // muunnos bool-tyypistä visibility-tyyppiin public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { bool arvo = (bool)value; if ( arvo ) return Visibility.Visible; return Visibility.Hidden; } // muunnos visibility-tyypistä bool-tyyppiin public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { Visibility arvo = (Visibility)value; if (arvo == Visibility.Hidden) return false; if (arvo == Visibility.Collapsed) return false; return true; } }
Käytetään XAMLissa seuraavasti:
<Window x:Class="luento13_2012.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" xmlns:oma="clr-namespace:luento13_2012"> <Window.Resources> <!-- otetaan oma konvertteri käyttöön ja määritellään sille avain --> <oma:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/> </Window.Resources> <Grid> <CheckBox Content="Neliö" Height="16" HorizontalAlignment="Left" Margin="12,54,0,0" Name="checkBox1" VerticalAlignment="Top" /> <Rectangle Margin="0,-200,0,0" Width="100" Height="100" Visibility="{Binding ElementName=checkBox1, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}" Fill="#FFC14D4D"></Rectangle> </Grid> </Window>
Resources
Resourceja voi määritellä XAMLissa lähes minkä tahansa elementin yhteyteen. Mitä korkeammalle tasolle puussa resurssi on määritelty sitä laajemmalti sitä voidaan käyttää.
Resurssiin viitataan joko staattisena (StaticResource) tai dynaamisena (DynamicResource) sen mukaan onko resurssi käytettävissä jo ohjelman käynnistysvaiheessa vaiko vasta myöhemmin tai muuttuuko se ohjelman ajon aikana.
Resursseja voi määritellä myöx app.xaml-tiedostoon jolloin ne ovat käytössä kaikissa projektin osissa
- WPF Tutorial - Binding Converters
- [WPF] The Power of Converters
- A Universal Value Converter for WPF
- Value Converter In WPF - Part I
- IValueConverter Interface
- ValueConversionAttribute Class
Tyylit
Tyyleillä saadaan helposti yhtenäinen ulkoasu kaikille kontrolleille. vrt. CSS-tyylit
Määritellään tyyli:
<Window.Resources> <!-- Määritellään oma tyyli checkbox-elementeille --> <Style x:Key="CheckBoxTyyli" TargetType="{x:Type CheckBox}"> <Setter Property="Background" Value="#FFD6D6EB" /> <Setter Property="FontFamily" Value="Verdana" /> <Setter Property="FontSize" Value="14" /> <Setter Property="FontWeight" Value="ExtraBold" /> <Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="VerticalAlignment" Value="Top" /> <Setter Property="Height" Value="16" /> </Style> <!-- Perintä toimii myös --> <Style x:Key="ErikoisCheckBoxTyyli" BasedOn="{StaticResource CheckBoxTyyli}" TargetType="CheckBox"> <Setter Property="FontSize" Value="34" /> <Setter Property="Height" Value="40" /> </Style> <!-- Oletustyyli kaikille buttoneille --> <Style TargetType="Button"> <Setter Property="FontSize" Value="24" /> <Setter Property="Height" Value="34" /> </Style> </Window.Resources>
Käytetään tyyliä:
<CheckBox Style="{StaticResource CheckBoxTyyli}" Content="Ympyrä" Margin="10,10,0,0" Name="checkBox2" />
- Displaying Data Validation Messages in WPF
- Introduction to Styles in WPF
- A Guided Tour of WPF Part 5 (Styles)
Triggerit
Triggerien avulla voidaan tehdä tapahtumista riippuvaisia tyylejä, datatemplateja ym.
<Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="Yellow"/> </Trigger> </Style.Triggers>
Samaan tapaan voidaan havainnollistaa virheitä syötteiden kohdalla:
<Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> </Style>
Data Templating
DataTemplaten avulla voidaan määritellä miten jokin tietty luokka esitetään. Apuna voidaan käyttää DataTriggereitä
<DataTemplate DataType="{x:Type oma:Henkilo}"> <Border BorderThickness="1" BorderBrush="Gray" Padding="7" Name="border" Margin="3" HorizontalAlignment="Stretch"> <StackPanel Orientation="Horizontal" Name="panel"> <TextBlock Margin="2" Text="{Binding Path=Etunimi}" Name="textBlockEtunimi"/> <TextBlock Margin="2" Text="{Binding Path=Sukunimi}" Name="textBlockSukunimi"/> </StackPanel> </Border> <DataTemplate.Triggers> <DataTrigger Binding="{Binding Path=Sukunimi}" Value="Doe"> <DataTrigger.Setters> <Setter Property="BorderBrush" Value="DodgerBlue" TargetName="border" /> <Setter Property="BorderThickness" Value="3" TargetName="border" /> <Setter Property="Padding" Value="5" TargetName="textBlockEtunimi"/> <Setter Property="Padding" Value="5" TargetName="textBlockSukunimi"/> </DataTrigger.Setters> </DataTrigger> <DataTrigger Binding="{Binding Path=Sukunimi}" Value="Lahtonen"> <Setter Property="BorderBrush" Value="Black" TargetName="border" /> <Setter Property="BorderThickness" Value="5" TargetName="border" /> <Setter Property="Padding" Value="15" TargetName="textBlockEtunimi"/> <Setter Property="Padding" Value="15" TargetName="textBlockSukunimi"/> </DataTrigger> </DataTemplate.Triggers> </DataTemplate>
ControlTemplate
Komponentin ulkoasu voidaan uusia kokonaan ilman, että tarvitsee luoda omaa komponenttia.
Uutta ulkoasua määritellessä on muistettava muutettavan kontrollin normaali toiminta ja siihen liittyvät erityisyydet. esim. painikkeessa on muistettava esittää painikkeen sisältö ja listboxissa listboxiin lisätyt elementit.
<Style TargetType="HeaderedItemsControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type HeaderedItemsControl}"> <StackPanel> <Grid> <Rectangle Fill="{TemplateBinding Background}"/> <ContentPresenter ContentSource="Header"/> </Grid> <Grid> <Rectangle Stroke="{TemplateBinding BorderBrush}"/> <ItemsPresenter Margin="2,0,0,0"/> </Grid> </StackPanel> </ControlTemplate> </Setter.Value> </Setter> </Style>
TemplateBinding sitoo komponentin sisäisten komponenttien ominaisuuksia komponentin ominaisuuksiksi.
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
Virheilmoituksista saadaan havainnollisempia:
<Style TargetType="TextBox"> <Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Foreground="Red" FontSize="20" Text="!"/> <Border BorderBrush="Red" BorderThickness="2"> <AdornedElementPlaceholder /> </Border> </StackPanel> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> </Style>
Käyttäjien kommentit