Lesson 2 - The XAML language in C# .NET WPF
In the previous lesson, Introduction to WPF (Windows Presentation Foundation), we introduced the WPF technology in C# .NET and created our first form (a form that displayed "Hello World" in a TextBlock). We also went over the fact that the graphic designer in Visual Studio is not very flexible and that we would mostly use XAML code to design our applications. This time, we are going to dive deeper into XAML and get fully acquainted with the language.
We already know that XAML is used to code application presentation layers. Simply put, we use XAML to design the visual representation of our application's window. XAML is based on XML which is a markup language whose main purpose is to help make flexible designs and make it easy for anyone to create their own markups. I'm sure many of you have heard of or dealt with XHTML, which is an XML derivative used for creating websites. Those of you who know HTML have a major advantage over the others. Nonetheless, you will eventually encounter several differences from XML, and will have to adapt.
XML stands for eXtensible Markup Language. XAML, as we said before is based on XML, and stands for eXtensible Application Markup Language. In other words, it is an XML made for creating applications.
We saw XAML in action last time when we made our first form. The graphic designer in Visual Studio generated it for us in that case, but we will get some hands-on experience this time around. The XAML code to create a window with a text box in it is as follows:
<Window x:Class="HelloWPF.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:HelloWPF" mc:Ignorable="d" Title="Hello" Height="130.616" Width="325.872"> <Grid> <TextBlock x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="91,42,0,0" Text="Hello world from forms!"/> </Grid> </Window>
Now, let's go over the basic build-up of XML and XAML using simple terms and examples.
XML documents consist of elements, whose overall structure is called a tree. Meaning that elements can contain any number of nested elements (elements can be nested in many, many layers of depth). However, every XML document can only hold one root element in which every other sub-element is nested.
The document above contains a Window root element, with a nested Grid element placed within it, you could think of a Grid as a panel for other controls, and in the Grid is a TextBlock element which we are already familiar with.
Note: XML usually includes headers, but we don't have to in XAML.
We write elements, sometimes referred to as tags, using angle brackets in which we place the element's type name. In XML, every element has to be closed (contrary to HTML where closing is optional). Elements are closed based on whether they're paired or unpaired. Unpaired elements are written as follows:
To close an unpaired element, we use a slash before the trailing angle bracket.
We close paired elements by placing another tag with the element name and the slash before the leading angle bracket. Paired elements are made so we can insert the contents or other elements within them. What the element actually does, is mark the contents and give them a particular meaning (it's extensible, and it marks things up!). Below, what we are doing is marking the text "Hello world from forms!" and setting it within a TextBlock's content.
<TextBlock>Hello world from forms!</TextBlock>
We can insert contents into an attribute as well. We declare attributes in the same way for both paired and unpaired elements - by writing the attribute name followed by the equals sign and the attribute's value in quotes:
<TextBlock Text="Hello world from forms!" />
The TextBlock element can be declared as both paired and unpaired elements and allows us to define its contents using either attributes or set directly within the tags. The element names, their attributes and whether they're paired or not is obviously by the language - which is XAML, in this case. In next couple of lessons, we'll go over the most commonly used and essential elements.
Every element can have any number of attributes, which are referred to as their properties. You cannot insert another element into an attribute, only text values are accepted.
Assuming you've read our object-oriented course about programming in C# .NET up until the end, you know that all namespaces in C# are, is packages containing individual classes. Namespaces were introduced due to the enormous amount of classes included in the .NET framework. Without namespaces, every class would have to have a unique name and would result in name collisions if we created a class that shared an identical name with any other .NET class.
When using namespaces, we specify which components from which namespaces we want to use at the beginning of the document. That way, we can have several components with the same name and not run into name collisions because we would only be using a single component from a single namespace at a time. Also, thanks to aliases, we are able to change a component's name in a given document. This enables us to use even more components with the same name at the same time but under different aliases (this entire paragraph refers to namespaces for components in general).
In C# .NET, namespaces mainly contain classes. Whereas in XML, namespaces contain elements. In other words, using namespaces, we specify which "tag packages" we want to use in a document. A common example would be using table elements, where a <table> element is taken once from the web namespace, which identifies it as a table, and once from the shop namespace, where it is identified as a desk.
We define the namespaces we want to work in the XAML Window element using the xmlns attribute (=XML Name Space). The designer prepares multiple "mark packages" for us in the generated code (which differ depending on which WPF you are using):
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:HelloWPF"
Although namespaces are identified using URLs, they are not actual web addresses, just names. The first namespace contains the basic elements needed for creating WPF applications, i.e. it is the default namespace). When we write tags, they are automatically taken from this namespace, e.g. the TextBlock element or the Window element.
The second namespace has an "x" alias assigned to it. In order to use tags from it, because it has an alias, we have to prefix their names with "x:". This particular namespace includes many extension parameter definitions. In the example code above, we see that the Window element has an x:Class parameter. What this does is specify the name of the class containing the C# code for handling the form, known as Code-Behind, which we will get into later on in the course.
Namespaces are also used for adding custom components, which we will also cover in the next couple of lessons.
Also, before we move on, notice how the Window element contains several parameters which set its width, height, and caption text.
You may be wondering what would happen if you inserted an angle bracket, quote or any other special character as an element or attribute content. What would happen is that the document would no longer be valid and may even result in runtime errors. That's why we have entities, which are essentially aliases for special characters like <,>, & ".
We write them like this:
< > & "
Writing out the text "5 > 6" in a TextBlock would need to follow the format below:
<TextBlock>5 > 6</TextBlock>
Lt means Less Than, and gt stands for Greater Than. Moreover, the ampersand, and the quote specify that the content is an entity declaration.
The next lesson, Positioning in C# .NET WPF, will be more practical. You will learn how to use different element attributes and will get to create more interesting form applications.