Windows Presentation Foundation (WPF)- Luento 10
Mikä on Windows Presentation Foundation ja miten se eroaa Windows Formsista? Tehdään yksinkertainen WPF-sovellus. Käydään läpi perusteet dependency propertieseista ja data bindingista.
Luentoesimerkki (luento10_wpf.zip)
- Luento 10 (Youtube)
- tjlahton2012-02-21_1859.mp4 45.0 Mt
- tjlahton2012-02-21_1859.wmv 70.0 Mt
- tjlahton2012-02-21_1859.mp3 22.6 Mt
Mikä on WPF?
- WPF on rakennettu DirectX-rajapinnan päälle ja tarjoaa laitteistokiihdytyksen ja modernimpia käyttöliittymäominaisuuksia kuin Windows Forms.
- WPF on resoluutioriippumaton ja vektoripohjainen.
- XML-pohjaisella XAML (Extensible Application Markup Language) kielellä määritellään käyttöliittymä.
Tämä mahdollistaa saman käyttöliittymän käyttämisen monissa ympäristöissä.
- XAMLin avulla käyttöliittymään voi määritellä tyylejä (vrt. WWW-sivuilla käytetty CSS).
- Käyttöliittymä ja ohjelmakoodi saadaan pidettyä hyvin erillään
- _ on sama kuin &-merkki windows formsissa.
- Omia kontrolleja ei tarvita niin usein
- Valmiit kontrollit voivat sisältää toisia kontrolleja. Esim. Button voi sisältää kuvan
- Tyyleillä voi muuttaa valmiin kontrollin ulkoasun
- DataTemplatella voi kustomoida tavan jolla kontrolli esittää tietoja. Esim. Combobox voisi listata valintaruutuja eikä vain tekstiä
- ControlTemplatella voi kokonaan uudelleenmääritellä kontrollin rakenteen
- Triggerit reagoivat kontrollin propertyjen arvoihin eli toimivat osittain tapahtumien korvaajina
- Data Binding
- Dependency properties
- Attached properties
- Routed Events
Looginen ja visuaalinen puu
WPF-käyttöliittymä on rakennettu hierarkisesti. Elementit sijaitsevat hierarkisessa puussa sisäkkäin. Tätä puurakennetta kutsutaan loogiseksi puuksi. Visuaalinen puu on laajennettu looginen jossa kaikki elementin on palasteltu pienimpiin osiinsa.
esimerkki jossa visuaalinen puu, jonka sisällä loogisen puun elementin ovat korostettuina.
Data binding
Databindingin avulla voi automaattisesti päivittää käyttöliittymää lähdetietojen muuttuessa.
Tietoja voi sitoa yksi- tai kaksisuuntaisesti.
Tietoja voi sitoa vain DependencyProperty-tyyppisiin propertyihin.
Kaikilla käyttöliittymäkomponenteilla on DataContext-propery, jonka voi sitoa toiseen elementtiin tai tietolähteeseen. DataContext on periytyvä.
Binding-luokka
- Source - viittaa tietolähteeseen
- Path - Mistä tietolähteen ominaisuudesta otetaan tietoja. Path on myös oletusproperty eli sitä ei tarvitse välttämättä erikseen mainita.
- ElementName - tietolähteenä käytettävän elementin nimi. Korvaa tarvittaessa Source-propertyn
- Converter - mahdollisesti tarvittava valueconverter, joka muuntaa tietolähteen tiedot sopivaan muotoon ja toistepäin.
- Mode - määrää mihin suuntaan tietoa sidotaan
- TwoWay
- OneWay
- OneTime
- OneWayToSource
<TextBox x:Name="TextBox1" Width="50" Height="20" /> <TextBox x:Name="TextBox2" Width="50" Height="20" Text="{Binding Path=Text, Mode=TwoWay, ElementName=TextBox1" />
Dependency properties
DependencyPropertyjen arvot selvitetään dynaamisesti eikä suoraan luokan privaatista attribuutista.
DependencyPropertyt tallennetaan DependencyObject-luokassa olevaan dictionary-tyyppiseen tietorakenteeseen. Avaimena toimii propertyn nimi.
Vain oletusarvoista poikkeavat arvot tallennetaan -> muistia säästyy.
Arvot periytyvät: Jos propertyn arvoa ei ole asetettu niin arvo haetaan loogisessa puussa ylemmältä tasolta.
<ListBox FontSize="20"> <TextBox>Esimerkkitekstiä. Tämä Textbox perii fonttikoon Listboxilta.</TextBox> <TextBox FontSize="15">Lisää esimerkkitekstiä. Tämä Textbox ei peri fonttikokoa Listboxilta.</TextBox> </ListBox>
Dependency propertyissa on sisäänrakennettu muutosilmoitusmekanismi, joka mahdollistaa datasidonnan.
// nimeäminen tehtävä juuri seuraavalla tavalla
public static readonly DependencyProperty LaskuriProperty =
DependencyProperty.Register(
"Laskuri",
typeof(int), // propertyn tietotyyppi
typeof(Autolaskuri), // luokka jossa property sijaitsee
new FrameworkPropertyMetadata(0, // propertyn oletusarvo
FrameworkPropertyMetadataOptions.AffectsRender, // vaikuttaa luokan ulkoasuun (textbox päivittyy)
new PropertyChangedCallback(OnValueChanged), // kutsutaan propertyn arvon muuttumisen jälkeen
new CoerceValueCallback(MuutaLaskuria))); // kutsutaan ennen propertyn arvon muutosta
// seuraavat tehtävä juuri näin. Ei mitään tarkistuksien lisäämistä
public int Laskuri
{
get { return (int)GetValue(LaskuriProperty); }
set { SetValue(LaskuriProperty, value); }
}
// tätä kutsutaan ennen laskurin muuttamista ja voidaan tässä vaiheessa
// tehdä tarkistuksia ja muuttaa laskuriin asetettavaa arvoa
private static object MuutaLaskuria(DependencyObject element, object value)
{
int luku = (int)value;
if (luku < 0) value = 0;
return luku;
}
// Laskuria on muutettu. Päivitetään tieto myös textboxiin
// parempi olisi bindata textbox tähän propertyyn:
// {Binding ElementName=IkkunanNimi, Path=Laskuri}
private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
Autolaskuri o = (Autolaskuri)obj;
o.textBoxLaskuri.Text = (Convert.ToInt16(o.textBoxLaskuri.Text) + 1).ToString();
}
dependency propertyn erikoistapaus Attached DependencyProperty liittää propertyja muihin luokkiin.
Lisätietoa
- Puut
- WPF Windows
- Application management
- Controls
- Commanding
- Layout
- WPF Layout sample
- Shapes and Basic Drawing
- Geometry
- WPF Brushes
- 3-D Graphics
- Animation
- Imaging
- Graphics and Multimedia
- Typography
- Documents
- Printing
- Content model
- Styling and templating
- ControlTemplate
- Data Templating
- Resources
- Control Authoringo
Käyttäjien kommentit