XAML

XAML steht für Extensible Application Markup Language. Es ist eine Auszeichnugssprache ähnlich HTML und dient primär zur Entwicklung von WPF Benutzerinterfaces. XAML wird wie HTML dazu verwendet, controls wie Buttons, Panels etc. auf eienem Fenster einer WPF Anwendung zu platzieren.

XAML kann ohne Unterstützung eines speziellen Tool von Hand quasi erstellt werden. Typischerweise wird jedoch im Bereich Grafik mit Expression Blend und in der Softwareentwicklung mit VisualStudio gearbeitet. Diese beiden Programme unterstützen eine WYSIWYG Bearbeitung von XAML. Mit XAML wird von Microsoft zum ersten Mal ein Workflow zwischen Grafiker und Softwareentwickler ermöglicht, weil eine Trennung von Darstellung und Programmcode erfolgt.

XAML ist auf Grund der XML Struktur nicht sehr effizient, weil es nicht kompakt ist. Aus diesem Grund existiert mit BAML (Binary Applicatioin Markup Language) eine binäre repräsentation von XAML. Beim Kompilieren wird jede XAML Datei in BAML konvertiert und in die DLL, oder EXE Assembly eingebettet.

XAML Namespaces

Jedes Element in der XAML Datei entspricht einer .NET Klasse. Der Name des Elementes enspricht exkat dem Klassenname. Element-Attriubte entsprechen den Properties dieser Klasse.

Der XAML Parser muss wissen, in welchem Namespace sich das Element, bzw. die Klasse befindet. XML namespaces (XAML basiert auf XML) werden als Attribute deklariert. Dies kann in jedem Start-Tag erfolgen. Per Konvention ist jedoch festgelegt, dass alle Namespaces im allerersten Tag des Dokumentes deklariert werden sollten. Ein einmal deklarierter Namespace ist dann Dokumentweit gültig.

Das xmlns Attribut ist ein spezialisiertes Attribut in der XML Welt, das für die deklarierung von Namespaces reserviert ist. Nachfolgend ein Beispiel zweier Namespaces, die in allen WPF XAML Dokumenten vorkommen:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Der erste Namespace umfasst alle WPF Klassen und die Controls zur Erzeugung von Benutzerinterfaces. Im Beispiel oben wird es ohne Namespace-Prefix verwendet, dadurch wird es als Standard bzw. Defaultnamespace im Dokument betrachtet.

Der zweite Namespace verwendet das x als Prefix und beinhaltet diverse utility features, wie das XAML Dokument interpretiert werden muss. Eine typische verwendung ist das Attribute x:Name in einem Control-Element.

Die XML Namespaces entsprechen keinen bestimten .NET Namespaces. Per Konvention werden Namespaces als URI angegeben. Diese URI’s ensprechen jedoch, auch wenn sie so aussehen, keiner realen Location im Internet. Die Wahl von URI liegt darin, dass eine Domain einer Firma auf der Welt einmalig ist und aus diesem Grund für die Eindeutigkeit eines Namespaces optiomal dienlich ist.

Code-Behind Klasse

Jedes XAML Dokument besitzt eine Code-Behind Klasse. Es stellt die Verbindung des Benutzerinterfaces zum Applikationscode her:

Window x:Class="WindowsApplication.DemoWindow"

Das Class Attribute aus dem x Namespace weist den Parser an, eine ensprechende Klasse mit diesem Namen zu erstellen. Die Klasse ist von der Klasse abgeleitet, die dem Element (oben also Window) entspricht. Die DemoWindow Klasse wird beim Kompilieren automatisch erzeugt. Durch den partial class Mechanismus von C# ist es möglich eine Klasse in mehrere separate Stücke (Dateien) zu unterteilen.

InitializeComponent

Diese Methode wird im Default Konstruktor eines Windows aufgerufen. Sie ist eine sehr wichtige Funktion in WPF Anwendungen. Wird ein anderer Konsturktor als der Default Konstruktor programmiert, dann muss in diesem zwingend die InitializeComponent() Methode aufgerufen werden.

Die Methode ist im CodeBehind nicht sichtbar, weil sie automatisch zur Kompilierungszeit erzeugt wird. InitializeComponents() extrahiert über LoadComponent() das BAML (kompiliertes XAML) und baut das Window/Benutzerinterface auf.

Name von Elementen

Solange ein Control im Code Behind nicht verwendet und manipuliert werden soll, braucht ein Element in XAML kein Name Attribute. Dies ist ein Unterschied zu Winforms, wo jedes Control zwingend ein Name haben muss. Sobald aber die Klasse bzw. die Instanz verwendet werden soll, braucht das Element ein Name Attribut.

x:Name="myButton"

Viele Klassen definieren ihr eigenes Name Property. Der XAML Parser kann damit umgehen und macht keinen Unterschied, ob der Prefix x (XAML Namespace) vorhanden ist, oder nicht.

Properties und Type Converter

In XAML werden die Eigenschaften über Attribute angegeben.

<TextBox Name="txtQuestion" 
  VerticalAlignment="Stretch" HorizontalAlignment="Stretch"  
  FontFamily="Verdana" FontSize="24" Foreground="Green" ... >

VerticalAlignment beispielsweise ist ein Property der Klasse TextBox. Die Zuweisung ist Stretch und in XAML eine Zeichenkette. Würde man im Codebehind die Eigenschaft setzen, dann müsste man direkt die Enumeration VerticalAlignment.Stretch verwenden (nicht einfach die Zeichenkette „Stretch“). Der XAML Parser übersetzt also alle Zuweisungen einer Property in den entsprechenden Datentyp. Hierzu verwendet der Parser die type converter, die es seit .NET 1 gibt.

Der XAML Parser ermittelt den passenden Typenkonverter nach folgendem Schema:

  1. Er berücksichtig explizit gesetzte Typenkonverter (TypeConverter Attribut) in der deklaration des Properties.
  2. Gibt es kein TypeConverter Attribute, dann überprüft der Parser den Datentyp und verwendet den entsprechendenn Konverter

XAML ist Casesensitiv und ein Element „button“ ist nicht gleich „Button“! Die Typenkonverter im Gegensatz dazu sind nicht Casesensitiv. „White“ oder „white“ ist exakt dasselbe und wird korrekt konvertiert.

Komplexe Properties können auch in einer property-element syntax angegeben werden:

<TextBox Name="txtQuestion" Foreground="Green"><TextBox.Foreground>Green</TextBox.Foreground></TextBox>

Markup Extension

Die Markup Extension ermöglicht es, nicht nur Statische Zuweisungen an Properties zu machen. Dynamische Werte z.B. Werte von anderen Controls können gebunden werden.

Markup Extensions werden in Attributen mit { } Klammern umschlossen:

<TextEdit Foreground="{x:Static SystemColors.ActiveCaptionBrush}" >

Der x Prefix zeigt an, dass sich die Extension im XAML Namespace befindet. Alle Markup Extensions sind von System.Windows.Markup.MarkupExtension abgeleitet. Markup Extensions beziehen sich zu Klassen, deshalb können sie in XAML auch als nested properties verwendet werden.

<TextBox Name="txtQuestion" Foreground="Green">
<TextBox.Foreground> <x:Static Member="SystemColors.ActiveCaptionBrush"></x:Static>
</TextBox.Foreground></TextBox>

 Attached Properties

Sind properties, die auf verschiedene Controls angewendet werden, aber in einer anderen Klasse definiert sind. Das bedeutet, dass ein Control das innerhalb eines anderen Platziert wird, dessen Properties übernehmen kann. Diese speziellen Properties sind dieses Attached Properties. Diese Properties bestehen immer aus zwei Teilen, nämlich dem Klassennamen und dem Propertynamen.

<TextBox x:Name="myTextBox" Grid.Row="0">Sampletext</TextBox>

Attached Properties sind keine echte Properties, sondern werden in Methodenaufrufe übersetzt. Der XAML Parser ruft die statische Methode auf: Grid.SetRow(). Der Parser verwendet dabei zwei Parameter. Das modifizierte Objekt und das Property Value.

Grid.SetRow(myTextBox, 0);

Der Code sugeriert, dass die RowNumber im Grid Ojekt gespeichert ist. Das ist aber nicht der Fall! Sie ist im TextBox Objekt gespeichert, weil die Klasse TextBox abgeleitet ist von der DependenyObject Basisklasse, wie es alle WPF Controls sind. Attached Properties sind sind spezialisierte Typen von Dependcy Properties. die Grid.SetRow Methode ist eigentlich auch nur ein Shortcut und Equivalent zu der Methode DependencyObject.SetValue():

myTextBox.SetValue(Grid.RowPropery, 0);

 

 

 

 

 

 

 

 

 

 

 

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*