XAML and the Declarative Paradigm
Windows Presentation Foundation (WPF) utilizes XAML (Extensible Application Markup Language), a declarative language based on XML, to define user interfaces. In XAML, tags represent object instantiations. For instance, nested tags indicate a parent-child relationship in the visual tree.
<Window>
<Grid>
<!-- This declares a Grid object inside a Window object -->
</Grid>
</Window>
Standard Project Anatomy
A typical WPF aplpication consists of several key components:
- Properties: Stores assembly metadata and resources.
- References: External libraries and dependencies.
- App.xaml: The application definition file, specifying the entry point and global resources.
- MainWindow.xaml: The primary UI definition, paired with a partial C# class (Code-Behind) for logic.
<Application x:Class="WpfApp.Core.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainView.xaml">
<Application.Resources>
<!-- Global styles and templates -->
</Application.Resources>
</Application>
Object Property Assignment
In XAML, properties can be assigned in two primary ways:
1. Attribute Syntax
Used for simple values like strings, numbers, or built-in types.
<Ellipse Fill="SteelBlue" Width="150" Height="100" Stroke="Black"/>
2. Property Element Syntax
Used for complex objects that cannot be expressed as a simple string. This uses the TypeName.PropertyName syntax.
<Button>
<Button.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Azure" Offset="0.0"/>
<GradientStop Color="RoyalBlue" Offset="1.0"/>
</LinearGradientBrush>
</Button.Background>
</Button>
The 'x' Namespace and Compiler Directives
The x namespace mapping (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml") provides directives for the XAML compiler:
- x:Class: Links the XAML file to a specific partial class in the Code-Behind.
- x:Name: Generates a field in the partial class to reference the UI element in C# code.
- x:Key: Uniquely identifies a resource within a ResourceDictionary.
- x:Type: Used for passing a Type object as a value.
- x:Static: References static fields or properties from code.
Data Binding Fundamentals
WPF shifts from the traditional event-driven model of WinForms to a data-driven model. Data Binding serves as the bridge between the UI (Target) and the business logic (Source).
Binding Mechanics
A Binding object requires a Source and a Path. For a target to update automatically, the source object must implement INotifyPropertyChanged.
public class Employee : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _fullName;
public string FullName
{
get => _fullName;
set
{
_fullName = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FullName)));
}
}
}
In the UI, the binding connects the target property to the source data:
<TextBox Text="{Binding FullName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
Binding Modes and Triggers
-
Binding Modes:
OneWay: Source updates the Target.TwoWay: Bidirectional updates.OneTime: Target updated only once at initialization.OneWayToSource: Target updates the Source.
-
UpdateSourceTrigger:
PropertyChanged: Updates occur immediately as the property changes.LostFocus: Updates occur when the UI element loses focus.Explicit: Updates only ocurr through code cals.
Value Converters
When the data type of the Source does not match the Target's expected type, a value converter (implementing IValueConverter) is used.
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool isVisible = (bool)value;
return isVisible ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
Visibility visibility = (Visibility)value;
return visibility == Visibility.Visible;
}
}
Usage in XAML:
<Window.Resources>
<local:BoolToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>
<TextBlock Visibility="{Binding IsActive, Converter={StaticResource BoolToVis}}" Text="Active Status"/>
Content Models
WPF controls are categorized by how they handle content:
- ContentControl: Holds a single child (e.g.,
Button,Window,Label). - ItemsControl: Holds a collection of items (e.g.,
ListBox,ListView,ComboBox). - HeaderedContentControl: A single child with an additional header (e.g.,
GroupBox,Expander). - Panel: Controls intended for layout containing multiple children (e.g.,
Grid,StackPanel,Canvas). - Decorator: Used to apply visual effects to a single child (e.g.,
Border).