Windows Presentation Foundation (WPF) - Pääteohjaus 4
Tee seuraavat tehtävät WPF-ohjelmaksi Visual Studiolla.
Suositeltavaa luettavaa ja katsottvaa: luento 10 ja luento 11 sekä Introduction to WPF ja WPF Tutorial.net
- Aloita uusi projekti ja valitse tyypiksi WPF Application
- Tee autolaskuri eli lisää ikkunaan painike ja laskukenttä. Säädä autolaskuri toimimaan myös näppäimistöllä L-kirjaimesta. Huomannet, että WPF:ssä _ on sama kuin &-merkki Windows Formsissa.
- Lisää ikkunan jokaiseen kulmaan label. Varmista, että labelit myös pysyvät kulmissa ikkunaa suurennettaessa.
Kts. esimerkki.
Toteuta lomake ensin käyttäen Grid Panelia ja sen jälkeen kokeile tehdä sama Dock Panelin avulla:
Dockpanel-versiossa kannattaa käyttää useampaa sisäkkäistä dockpanelia tai stackpaneleja dockpanelin sisällä.
- Sijoita keskelle ikkunaa Canvas Panel. Piirrä Canvaksen sisään viiva (Line) ja laatikko (Rectangle) ja ympyrä (Ellipse). Huomaathan, että OnPaint-metodia et tarvitse WPF:ssä.
- Liitä jokainen uusista labeleista seuraamaan autolaskuria eli näyttämään laskurin lukema. Tämä pitää onnistua
ilman ohjelmakoodia datasidontaa käyttäen.
Sidotaan labelin Content-ominaisuus labelLaskuri-objektin Content-ominaisuuteen:
<Label><Binding ElementName="labelLaskuri" Path="Content" /></Label>
Sama kuin edellä mutta attribuuttina:
<Label Content="{Binding ElementName=labelLaskuri, Path=Content}" />
- Varmista, että kaikki labelit toimivat.
- Lisää ikkunan vasempaan ja oikeaan laitaan Slider. Liitä (bind) ikkunaan piirtämäsi laatikon koko riippumaan vasemman laidan sliderin Value-ominaisuudesta. Liitä ympyrän koko riippumaan oikean laidan sliderista.
- Tee autolaskuri koostettuna WPF-komponenttina (WPF User Control Library). Kokeile komponenttisi toimintaa ja sijoita WPF-ohjelmaasi kolme autolaskuria. Aseta autolaskurit riviin ikkunan alalaitaan. Käytä tässä apunasi Stack Panelia.
- Määritä komponenttisi painikkeelle ja laskurikentälle järkevä minimileveys ja minimikorkeus.
- Lisää autolaskurikomponenttiisi Laskuri-property DependencyPropertyna:
// 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 labeliin private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { Autolaskuri o = (Autolaskuri)obj; o.labelLaskuri.Content = args.NewValue; }
Kokeile propertyn toimintaa ja sido jokainen ikkunan nurkissa sijaitsevista labeleista eri autolaskuriin. - Lisää ikkunaasi menut:
- File
- Open
- Save
- Close
- Help
- About
- File
- Lisää ikkunan vasempaan laitaan sliderin alapuolelle neljä valintaruutua joilla voit säätää nurkissa sijaitsevat labelit näkyviin tai pois näkyvistä. Yksi valintaruutu vastaa siis yhtä labelia. Jos ruutu on valittuna on label näkyvissä.
- Lisää ikkunan oikeaan laitaan siellä olevan sliderin alapuolelle kolme radiopainiketta. Radiopainikkeella voi valita mikä canvakselle piirretyistä kolmesta objektista (viiva, suorakaide, ympyrä) on näkyvissä. Vain yksi kerrallaan voi olla näkyvissä.
- Olisiko edellämainittuihin näkyvissä/ei näkyvissä valintoihin olemassa fiksumpaa toteutustapaa kuin käsitellä eri tapahtumavaihtoehdot? Binding? ;) Parannellaan ratkaisua myöhemmin...
Lisätietoa
Walkthrough: Constructing a Dynamic Layout
Walkthrough: Creating a Resizable Application by Using the WPF Designer
WPF Tutorial - Layout-Panels-Containers & Layout Transformation 2
Käyttäjien kommentit