Tehdään WPF-sovellus - 13 - Painikkeen uusi ulkoasu

- 4 mins

Tyylitellään Button

Painike.

Painike.

Painikkeemme on nykyisellään hurjan tylsän näköinen. Harmaa erämaa, jossa elämää ei ole. Synkkä taivas, jolla ei ole tähden tähteä. Metsä, joka ei vastaa kun sinne huudetaan. No. Ehkä sait jo ajatuksesta kiinni, joten aloitetaan!

Tämä on jo tuttua puuhaa, eli tehdään seuraavat muutokset App.xaml:iin:

<Style TargetType="Button">
        <Setter Property="Background" Value="#EB1555" />
        <Setter Property="BorderBrush" Value="#EB1555" />
        <Setter Property="FontFamily" Value="Calibri" />
        <Setter Property="FontSize" Value="48" />
        <Setter Property="Foreground" Value="White" />
</Style>
App.xaml - Button-tyyli.

Kaikki hyvin tähän saakka? Öh, eipä oikeastaan. Nopea vilkaisu Designeriin herättää ehkä hieman hämmennystä:

Mikä tässä on pielessä?

Mikä tässä on pielessä?

Määrittelimme aiemmin, että Foreground (eli painikkeen tekstin väri) olisi arvoltaan White. Kuvaa katsomalla voimme vain todeta, että “Ei.. Ei se ole valkoinen”. Mikä tässä on vialla?

Elementtien sisällä on elementtejä

Button itsessään koostuu useammasta elementistä. Voimme havainnollistaa tätä käynnistämällä sovelluksen ja tarkastelemalla Live Visual Tree -ikkunasta painikkeen elementtiä tarkemmin. Varmista, että “Show Just My XAML” ei ole päällä, jotta voimme “porautua” WPF:n omienkin kontrollien hierarkian sisään:

Live Visual Tree - "Show Just My XAML"

Live Visual Tree - "Show Just My XAML"

Live Visual Tree - Porauduttu syvemmälle

Live Visual Tree - Porauduttu syvemmälle

Kappas kummaa. Mitäpä sieltä löytyikään: TextBlock!

Tämä selittää sen, että miksi painikkeen tekstin väri ei olekaan valkoinen vaan harmaa. Tyylittelimme kaikki sovelluksen TextBlock-elementit esittämään tekstinsä harmaana. Painike kunnioittaa tätä sääntöä, joten miten korjaamme asian?

Ylikirjoitetaan painikkeen sisältö

Ei ole häpeä etsiä tietoa.

  • Minä, 2021

Useimmissa tapauksissa emme ole yksin ongelmiemme kanssa. Ei ole siis mitään syytä olla turvautumatta kattavaan tietopankkiin: Internetiin. Käyttämäni hakukone tuotti kirjoitushetkellä hakusanoilla “wpf button textblock style” 239 000 tulosta, joista ensimmäisten joukossa oli vastaus ongelmaamme: StackOverflow - How are WPF Buttons and TextBlock styles related?.

Ratkaisu on siis hyvinkin yksinkertainen: Kerromme erikseen, ettemme halua painikkeen sisäiselle tekstilaatikolle mitään tyylimäärittelyä. Asetetaan tyylin arvoksi siis Null ja siirretään teksti painikkeelta TextBlock-elementille:

<Button Grid.Row="2"
        Click="Button_Click">
    <TextBlock Style="{x:Null}"
               Text="CALCULATE" />
</Button>
MainWindow.xaml - Painikkeen uusi määrittely.

Buttonin teksti näyttää nyt paremmalta

Buttonin teksti näyttää nyt paremmalta

Kun nyt käynnistämme sovelluksen, niin kaikki vaikuttaa taas olevan ok.

Kunnes liikutamme kursorin painikkeen päälle:

Painikkeen hover on väärän väärinen

Painikkeen hover on väärän väärinen

Painikkeen hoverin väri ei oikein vastaa muuta tyyliä, joten korjataan asia määrittelemällä ensimmäinen interaktiivinen toiminto tyylien kannalta: hoveroinnista painikkeen taustavärin vaihtaminen!

Hover-väri korjataan triggereillä

WPF:ssä interaktiivisia toimintoja voi toteuttaa käyttämällä triggereitä. Lisätään painikkeen tyylille triggeri, joka muuttaa painikkeen väriä kursorin ollessa sen päällä:

<Style.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
        <Setter Property="Background" Value="#31142F" />
    </Trigger>
</Style.Triggers>
App.xaml - Button-tyyliin lisätty trigger.

Käytännössä tämän määrittelyn voisi lukea näin auki: “Kun painikkeen IsMouseOver-arvo on True (kursori on elementin päällä), niin asetetaan Background arvoon #341142F (vaihdetaan taustaväri).”

Törmäämme jälleen yhteen WPF:n omituisuuksista: Painikkeen sisäisissä tyylimäärittelyissä on määritelty erikseen IsMouseOver-triggeri, joka ylikirjoittaa oman triggerimme. Ratkaisuna tähän voimme kiertää oletustyylin pakottaman hover-tyylittelyn korvaamalla painikkeen tyylissä Template-arvon:

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
            <Border Background="{TemplateBinding Background}">
                <ContentPresenter HorizontalAlignment="Center"
                                  VerticalAlignment="Center" />
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>
App.xaml - Button-tyyliin korjattu Templaten määrittely.

Hover korjattu

Hover korjattu

Hienoa! Painikkeemme vaikuttaisi olevan nyt viimeistelty.

Voimme seuraavaksi käydä käsiksi elementtien asemointiin ikkunan sisällä ja lisätä yksiköiden tekstit takaisin paremmille paikoilleen.

Anssi Kettunen

Anssi Kettunen

Ohjelmistokehittäjä suorittamassa tehtävää 🦊

rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora