Podstawy WPF

1. XAML – język interfejsu użytkownika

XAML, czyli eXtensible Application Markup Language, to język oparty na XML, który Microsoft stworzył specjalnie do deklaratywnego definiowania interfejsów użytkownika. Jego główną zaletą jest to, że pozwala opisywać wygląd aplikacji w sposób podobny do tego, jak HTML opisuje strukturę stron internetowych, ale z znacznie większymi możliwościami.

Deklaratywność XAML oznacza, że programista opisuje „co” ma być wyświetlone, a nie „jak” to należy zrobić. Zamiast pisać dziesiątki linii kodu C# tworzącego kontrolki, wystarczy kilka linii XAML, które jasno opisują pożądany rezultat.

Podstawowa składnia XAML

Każdy dokument XAML jest poprawnym dokumentem XML, co oznacza, że musi przestrzegać podstawowych zasad składni XML. Każdy element musi mieć tag otwierający i zamykający, lub być samozamykający. Atrybuty muszą być ujęte w cudzysłowy, a struktura dokumentu musi być hierarchiczna.

Podstawowa struktura okna WPF w XAML:

<Window x:Class="MojaAplikacja.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Moje pierwsze okno WPF" 
        Height="400" Width="600">
    
    <Grid>
        <!-- Tutaj umieszczamy elementy interfejsu -->
    </Grid>
    
</Window>

Element Window to główny kontener reprezentujący okno aplikacji. Atrybut x:Class łączy ten dokument XAML z odpowiadającą mu klasą C# – w tym przypadku MainWindow. Przestrzenie nazw definiowane przez xmlns informują parser XAML, gdzie szukać definicji używanych elementów.

Właściwości w XAML

XAML oferuje dwa główne sposoby definiowania właściwości elementów. Najprostszy to składnia atrybutów:

<Button Content="Kliknij mnie" 
        Width="120" 
        Height="40" 
        Background="LightBlue"/>

Przestrzenie nazw w XAML

Przestrzenie nazw w XAML działają podobnie do przestrzeni nazw w C# – pomagają organizować i identyfikować różne typy elementów. Domyślna przestrzeń nazw zawiera wszystkie standardowe kontrolki WPF. Przestrzeń nazw x zawiera elementy specyficzne dla XAML, takie jak x:Class, x:Name czy x:Key.

Komentarze w XAML

XAML obsługuje komentarze XML, które pomagają dokumentować strukturę interfejsu:

2. C# w kontekście WPF – kod za interfejsem

Podczas gdy XAML definiuje wygląd aplikacji, kod C# jest odpowiedzialny za jej zachowanie i logikę. W WPF te dwa elementy są ściśle ze sobą powiązane poprzez mechanizm zwany „code-behind” – każdy plik XAML ma odpowiadający mu plik C# zawierający klasę, która obsługuje zdarzenia i implementuje logikę interfejsu.

Struktura klasy code-behind

Każde okno WPF składa się z dwóch plików: MainWindow.xaml zawierającego definicję interfejsu oraz MainWindow.xaml.cs zawierającego kod C#. Klasa code-behind dziedziczy po odpowiedniej klasie bazowej i jest oznaczona słowem kluczowym partial.

using System.Windows;

namespace MojaAplikacja
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // Dodatkowa inicjalizacja
        }
    }
}

Metoda InitializeComponent() jest kluczowa – to ona ładuje i przetwarza kod XAML, tworząc rzeczywistą strukturę kontrolek i łącząc je z kodem C#.

Dostęp do elementów z kodu C#

Aby uzyskać dostęp do elementu zdefiniowanego w XAML z poziomu kodu C#, element musi mieć zdefiniowany atrybut x:Name:

<TextBox x:Name="txtImie" Width="200"/>
<Button x:Name="btnZapisz" Content="Zapisz" Click="BtnZapisz_Click"/>

Odpowiadający kod C#:

private void BtnZapisz_Click(object sender, RoutedEventArgs e)
{
    string imie = txtImie.Text;
    
    if (string.IsNullOrEmpty(imie))
    {
        MessageBox.Show("Proszę wprowadzić imię!");
    }
    else
    {
        MessageBox.Show($"Witaj, {imie}!");
    }
}

3. Relacja między XAML a C# – podstawy współpracy

Zrozumienie relacji między XAML a C# jest kluczowe dla efektywnego programowania w WPF. Te dwa języki nie działają niezależnie – są ze sobą ściśle zintegrowane i tworzą spójny system.

Proces kompilacji

Gdy kompilujemy projekt WPF, kompilator XAML analizuje pliki .xaml i na ich podstawie generuje kod C#, który jest następnie kompilowany razem z naszym kodem. Ten wygenerowany kod zawiera definicje wszystkich elementów zdefiniowanych w XAML.

Separacja odpowiedzialności

Jedna z najważniejszych zasad architektury WPF to czysta separacja między prezentacją (XAML) a logiką (C#). XAML powinien zawierać wyłącznie definicje interfejsu użytkownika, a kod C# – logikę biznesową i obsługę zdarzeń.