You should now have a basic understanding of what WPF is and when and why you should use it. Now come the components of WPF. The first thing you should understand, when developing WPF applications is XAML. XAML is the core of WPF applications (also of silverlight, but more of that later).
XAML stands for Extensible Application Markup Language. You pronounce it as “zamel”. It is an XML based language used for creating user interfaces in WPF + for serializing .NET object instances into a human readable format. It is also used by the workflow foundation for defining workflows but that is beyond the scope of this tutorial. The main advantage that XAML provides is declarative UI. You can create UI elements in the xaml, and then separate the visual aspect from logic by putting the logic in code-behind files (xaml.cs), joined to xaml through partial class definitions.
XAML is different from other markup languages in that it represents the instantiation of objects defined in the WPF (or silverlight) assemblies (these are called backing type objects). This means xaml has a direct tie to the backing type system unlike other markup languages.
XAML files are typically encoded as UTF-8.A xaml file, unsurprisingly has the extension of .xaml. XAML can be compiled or interpreted but you can embed c# code in Xaml only when it is compiled. WPF applications created using visual studio compile the XAML. Visual Studio creates a code-behind file for each XAML file. Basically, the x:class attribute in the XAMl joins the partial code-behind file (xaml.cs) to the xaml and thus the file can emit code. Then the entire thing is compiled into a BAML (Binary Application Markup Language) file. The main reason why XAML is compiled into BAML and not IL is that BAML is compact (hence better for xbap application downloads), safer and can be localized.
You can also create “loose” XAML’s to host on the browser that are parsed and interpreted during runtime (just create a simple, static content XAML file in visual studio and right click – open it using internet explorer). Such files cannot emit code because you cannot have the x:class attribute in loose xaml files. It is possible to load a loose XAML file by calling XamlReader.Load() method, casting the return value into the root element. The loose XAML version provides a dynamic way to load and change the view, but provides poor performance due to the fact that the XML file is parsed at runtime. This is useful when you want to change the view dynamically but the poor performance and limited server interactivity makes this a bad option, there are better ones.
So, now that you have understood the basics of WPF and XAML, let us get started with the usage.
We will be working only with Visual Studio 2012 in these tutorials. While it is possible and sometimes easier to create XAMLs that are interpreted, in real life, such XAML-only applications are very, very rare. So, before beginning, you should install Visual Studio 2012 (there is no need to install .Net framework separately, it comes with VS). After installing it, set it for developer settings. Now open the IDE (Integrated Development Environment, which in this case is Visual Studio 2012).
Now open File-New-Project and you will see the “WPF Application template”.
You will also see the WPF Browser application template which allows you to create a WPF application that behaves like a browser with forward and backward navigation buttons. You also see WPF custom and user control library templates (you may not see this if you are using the express edition) but more on that later. For now, we will concentrate on windows applications. So, give a name to your project, specify a location and click on OK. Visual Studio will now create a basic template of WPF application, with a XAML called MainWindow.xaml. It also creates other things like references and an App.Xaml. The references folder basically contains all the assemblies that you will be using in your WPF program, but if you have a background in .Net, you will already know that. The App.xaml is an application-level xaml, which is used to store resources that are common or re-used through the application. Within this, you see a line like this:
This essentially specifies the xaml that will launch when the application starts. If you want to add a new xaml, just change the name to the new file here. Now, you can see that the MainWindow.xaml file contains only the markup. If you want to see the associated code-behind file, you need to click on the expansion arrow and it shows MainWindow.xaml.cs. Developers familiar with aspx pages will already have an idea about code-behind files, but even otherwise their use will become clearer as we progress. In WPF, the main idea is to separate visual rendering of the application from actual code/business logic. This is the “separation of concerns” which was discussed to an extent in the first tutorial. For example, if your team has a designer and a developer who are working parallely on an application screen, they can do their own thing on the xaml and xaml.cs respectively without waiting or spoiling the work of the other. Of course, sometimes it is easier said than done but you will see that WPF is actually efficient in this.
Note: If you are familiar with .Net 2.0 and above, you presumably know all about partial classes. Essentially, it is one class that is split into multiple files, and the compiler combines them into a single file. The files can be of different types, and each of them are identified as part of a whole through their name and the “partial” keyword. Partial classes can be useful when extending generated classes to add some behavior, or for separation of concerns. Here, the xaml and xaml.cs files are partial classes that together make a whole. The x:Class attribute at the top of the MainWindow.xaml (x:Class=”FontViewer.MainWindow”) configures the compiler to combine partial classes between markup and code-behind into a single file.
So, now you have the basic file and when you run it (click on the green arrow-like button at the top, your application opens a blank window):
So, there you are!! Your first WPF application is running.
As you can see, the root element in the main Xaml is “Window”. This belongs to the System.Windows.Window namespace. There are other root elements such as “Page” that you can use too. These belong to the System.Windows.Controls namespace and represent WPF controls.
You can also see that the default namespace (xmlns) in the XAML is http://schemas.microsoft.com/winfx/2006/xaml/presentation which, if you remember the previous lesson, is one of the two allowed default namespaces in silverlight. The namespace with the x: prefix denotes the more generic, and less used, features of XAML. Within the window, you have a “Grid”, which is again a WPF control that contains the elements you add and helps in visual arrangement of other controls in rows and columns. There are other similar controls like DockPanel etc which we will cover later. Now let us add a Textbox control and Button control to the above XAML within the grid.
<TextBox x:Name=”textbox”>Hello World</TextBox>
<Button x:Name=”button” Width=”100″ Height=”90″>Click me</Button>
When you run the application, this is what you have:
In fact, as you can see, you don’t even need to run the application for simple tasks like this. The design editor at the top half of the split pane makes it easy to see how your finished XAML would look like. Whatever you type in the xaml file gets reflected immediately in the design pane and vice versa.
In the above XAML, we have added instances of System.Windows.Controls.Button and System.Windows.Controls.Textbox to the grid. The attributes of these elements represent the properties of the object instance. In case of button, we have set the width, height and content properties, whereas in case of textbox we have set the content property alone. Content is a special type of property and you can set it either as shown above, or by explicitly specifying it as an attribute: <Button Content=”Click Me”>
On the other hand, the x:Name attribute is not a property of the object instances but is a special attribute that uniquely identifies the object. This is useful when you need to access it in the code. In other words, it is the same as creating an instance of Button class called “button” in the code as below:
Button button = new Button();
Of course, the button object also has a “Name” property of its own, and this can also be used to perform the same function. The x:Name is a more generic way of WPF recognizing individual elements, and it can be used with all controls.
In the next lesson, we learn a bit more about properties, and how to set properties that aren’t simple types. We will also learn about Markup extensions in the next lesson.