XAML (Extensible Application Markup Language) on Microsoftin kehittämä XML-pohjainen merkintäkieli, jota käytetään Windows-sovelluksien käyttöliittymien rakentamisessa eli graafisen näkymän toteuttamisessa. XAMLin käyttäminen graafisen sovelluksen toteuttamisessa erottaa käyttöliittymän ja sovelluksen toteuttavan ohjelmointikoodin omiin eri tiedostoihinsa, jolloin useampi henkilö voi hyvin työstää projektia kokonaisuutena. Visual Studio sisältää editorin sekä ohjelmistokehitykseen sekä käyttöliittymäsuunnitteluun (Blend for Visual Studio). Tällä opintojaksolla käytetään kuitenkin Visual Studion omaa XAML-editoria GUI-ohjelmoinnissa. Halukkaat voivat tutustua Blendin käyttöön itsenäisesti.
XAMLin käyttämä syntaksi on hyvin samankaltaista kuin kaikissa XML-pohjaisissa kieliessä (sinulle tuttuna esim. webbisivut ja HTML). XAML-elementit alkavat aina <-merkillä ja päättyvät >-merkkiin. Näiden merkkien sisälle määritellään ensin se mistä elementistä on kyse ja mahdolliset attribuutit arvoineen (erotellaan välilyönnen). Käytettävissä olevat elementit on määritelty kunkin sivun alussa .NET-nimiavaruuksien avulla.
XAML-dokumentilla on aina yksi juurielementti, jonka kautta voidaan määritellä XAML-dokumentin käyttämät nimiavaruudet. Nimiavaruuksien tarkoitus on määritellä XAML-dokumentissa käytettyjen elementtien ja niiden attribuuttien sijainti (eli se missä ne on määritelty).
<Page
x:Class="FirstApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FirstApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
...
</page>
<Window
x:Class="ooFirstWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ooFirstWpf"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" FontSize="14">
<Grid>
<Button x:Name="infoButton" Content="Click me!" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="infoButton_Click"/>
</Grid>
</Window>
Kaikissa XAML-dokumenteissa määritellään xmlns- ja xmlns:x-nimiavaruudet, jotka määrittelevät käytettävien WPF-komponenttien sijainnin sekä XAML-ominaisuudet, joilla voidaan vaikuttaa luotavan sovelluksen käyttöliittymään. Yksi tärkemmistä asia on yhdistää XAML ja sen taustalla toimiva ohjelmointi. Tämä toteutetaan ns. Code-Behind-luokkana, joka yllä olevassa näkyy rivillä 3. Tässä XAML-merkintäkieli yhdistetään x:Class="FirstApp.MainPage"-määrittelyllä käytössä olevan sovelluksen MainPage.xaml.cs-luokkaan. Jos XAML-dokumentista halutaan päästä omaan paikalliseen projektiin, tulee määritellä xmlns:local-nimiavaruus. Kolme alimmaista määrittelyä (xmlns:d) ovat käytössä tavallaan käyttöliittymän rakentamisen aikana (Desing Time, esimerkiksi Blend for Visual Studion käytön yhteydessä). Määrittely tavallaan kertoo XAML-jäsentimelle ettei se tulkitse ko. elementtejä suorituksen aikana.
UWP/WPF-sovelluksen jokaisen sivuun/ikkunaan liittyy oma, erillinen C#-kielinen luokka (partial class) esim MainPage/MainWindow, jota kutsutaan sovelluksen käynnistyessä (paljon muutakin tapahtuu, mutta avataan niitä asioita myöhemmin).
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace HelloWorld
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
}
}
WPF-sovelluksen CodeBehind-tiedoston MainWindow-luokka
using System.Windows;
using System.Windows.Controls;
namespace ooFirstWpf
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
Käytettävissä olevat kontrollit löytyvät Visual Studion Toolbox-valinnan kautta (Visual Studion vasemmasta reunasta). Kontrolli saadaan käyttöön yksinkertaisesti vetämällä se Toolboxista Visual Studion design-näkymään. Pudottamisen jälkeen kontrolli jää näkyville design-tilaan sekä sen käyttämä määrittely on näkyvissä myös koodieditorissa. Tämän jälkeen halutun kontrollin ominaisuuksia voidaan muuttaa Properties-ikkunan kautta tai suoraan muokkaamalla kontrollin ominaisuuksia koodieditorin kautta.
Käytettäviä XAML kontrolleja on useita kymmeniä. Kannattaa käydä listat huolellisesti läpi ja opetella tuntemaan käytössä olevat kontrollit.
Tässä hyvä lista WPF-kontrolleista: WPF Controls
Tässä hyvä lista UWP/Windows10:n kontrolleista : Controls list (XAML).
XAMLin jokaista elementtiä vastaa C#:n luokka. Näin ollen jokainen kontrolli voidaan tehdä myös ohjelmallisesti ja sisällyttää haluttuun ikkunaan. Joskus erittäin dynaamissa sovelluksissa on näin myös pakko menetellä, jos käyttöliittymä on mahdotonta suunnitella etukäteen.
Alla on näkyvissä XAML-dokumentti, joka määrittelee käyttöön yhden Button-kontrollin.
<Grid x:Name="ContentPanel" Margin="12,0,12,0">
<Button Height="72" Width="160" Content="Click Me" />
</Grid>
Sama asia voidaan tehdä käyttämällä C#-ohjelmointia.
// initialize button object
Button button = new Button();
// set properties
button.Width = 160;
button.Height = 72;
button.Content = "Click Me";
// Attach it to the visual tree, specifically as a child of a Grid object (named 'ContentPanel') that already exists.
// In other words, position the button in the UI.
ContentPanel.Children.Add(button);
Yksi tärkeimmistä asioista ohjelmoinnissa on toteuttaa sovelluksen tapahtumien käsittely huolellisesti. On täysin varmaan, että kukaan ei käytä sellaista sovellusta, joka toimii miten sattuu käyttäjän interaktivoiden seurauksena. Visual Studiossa on helppo valita haluttu kontrolli design-tilassa ja tämän jälkeen katsoa Properties-ikkunan kautta mitä kaikkia tapahtumia ko. kontrollille voi tapahtua. Tämän jälkeen klikataan haluttua tapahtuman kohtaa Properties-ikkunasta, ja Visual Studio liittää määritellyn tapahtuman XAML-kontrolliin ja tekee taustalla toimivaan luokkaan myös tapahtuman käsittelijän metodin. Ohjelmoijan vastuulle jää itse tapahtuman ohjelmointi eli mitä silloin sovelluksessa pitää tapahtua.
Yllä olevassa kuvassa on määritelty infoButton-kontrollille Click-tapahtumankäsittely. Visual Studio generoi XAML-tiedoston taustalla toimivaan luokkaan vastaavan metodin, jota kutsutaan, kun loppukäyttäjä painaa ko. Button-kontrollia hiirellä. Metodille määritellään kaksi parametria: ensimmäinen on viite objektiin, johon tapahtumankäsittelijä on liitetty (objekti voidaan tyyppimuuntaa haluttuun varsinaiseen kontrollityyppiin) ja toinen käsittelee itse tapahtumaan liittyvää tietoa.
private void infoButton_Click(object sender, RoutedEventArgs e)
{
infoTextBlock.Text = "My first UWP app!";
}
Tapahtumienkäsittely voidaan liittää kontrolleihin myös XAML:n koodieditorin kautta koodia kirjoittamalla. Esimerkiksi Button-kontrollille voidaan määritellä kirjoittamalla Click-attribuutti, jolloin Visual Studio osaa ehdottaa tapahtumienkäsittelijän muodostamista. Avautuvasta listasta voidaan valita jo mahdollisesti tehty tapahtumienkäsittelyyn liittyvä metodi tai valita tehtäväksi uusi (jolloin metodi generoituu taustalla toimivaan ohjelmointiin).
Tapahtumienkäsittely voidaan kiinnittää käyttöliittymien kontrolleihin myös suoraan ohjelmointikoodista ilman, että XAML-kontrolliin on liitetty tapahtumankäsittelyä. Tässä tapauksessa kontrollille tulee määritellä nimi eli tunniste, jotta siihen saadaan kohdistettua ohjelmointia.
<Button x:Name="myButton"/>
Nyt XAML:ssa määritelty Button-kontrolli on näkyvissä siihen liitetyssä luokassa ja sitä voidaan käyttää seuraavasti:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
// attach event handling
myButton.Click += Button2_Click;
}
private void Button2_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Button 2 clicked!");
}
}
Tämän jälkeen sovelluksen toteuttaminen on XAML-dokumentaation muokkaamista siten, että halutunlainen käyttöliittymä saadaan suunniteltua. Ohjelmointikoodien kirjoittamista XAML:in taustalla toimivaan luokkaan/luokkiin ja sekä hajauttamista olio-ohjelmoinnin mukaisesti useampiin luokkatiedostoihin. Sovelluksen käytössä voi olla useita XAML/CS-tiedostojen määrittelemiä näyttöjä, joita esitetään loppukäyttäjälle sovelluksen interaktioiden mukaisesti.
XAML overview
XAML namespaces and namespace mapping
Create a UI with XAML
Define layouts with XAML
Add controls and handle events
Controls list (XAML)