Back to the Future of Windows Applications

This article is an introduction to developing a Windows Vista application using the Windows Presentation Foundation (WPF), formally code-named 'Avalon', and the designer for the next version of Visual Studio, code-named 'Orcas'.

WPF provides the means to develop a new enriched application for Windows Vista. Perhaps the most important advantage of WPF is the separation between the user interface design and the implementation of the business logic of the application. That means people who are good designers can concentrate on the visual aspects of the application, and the good developers can work on implementing the business logic. It also eases the tailoring of the application for different customers by maintaining the same core implementation but providing different user interfaces.

Before going further, you need to make sure that you have installed all of these components:

  • WinFX runtime components (Pre-release February 2006 CTP), 2.5 Mb
  • Visual Studio 2005; if you don't have it, an Express Edition will suffice.
  • Windows Vista SDK (February 2006 CTP). The download file is a DVD image with the size of about 1 Gb. The image file is a CloneCD specific file and cannot be burned with any software, for instance Nero, but also works with Alcohol. However, you can download a file called Setup.exe from the same location, save it on the same folder on your hard disk, and run it. It will mount the image file and you will be able to proceed with the installation. Notice that you must install the Windows Vista SDK after Visual Studio; otherwise, some parts of the SDK will be overwritten during the Visual Studio installation. If you already have a prior CTP installed, you have to uninstall it first and only then install the February pre-release.
  • Development Tools for WinFX (March 2006 CTP), 3.7 Mb

XAML says "Hello Windows Vista!"

XAML stands for eXtensible Application Markup Language and is a declarative, XML-based language that allows you to build WPF interfaces. If you have installed the Windows Vista SDK, you can use the tool called XAMLPad that you can use to write XAML code. It has an editor where you can write the XAML code, which is interpreted on the fly and the result is displayed in the upper pane.

Amazingly, you have not built a "Hello World" application as is usually done in any new language, but a "Hello Windows" application. In this example, I created a page that holds a TextBlock that uses a font called "Palace Script MT" (notice that you might not have this font on your machine) of size 72, with the foreground color (font color) BarkBlue and the background color #FFDDEEFF (this is a RGBA color, with a completely transparent Alpha channel).

To learn more about XAML, I recommend reading this article, The Mists of Avalon by Guido Stercken-Sorrenti. The focus of this article is not teaching XAML, but rather showing you how to build applications with WinFX.

Although the XAMLpad could be a good tool to practice writing simple XAML user interfaces, when it comes to building a more complex application, something more powerful could be more helpful.

Introducing Cider

The Development Tools for WinFX contains a preview of the WPF designer for the next version of Visual Studio (code-named 'Orcas'). This new designer is code-named 'Cider'. When you start Visual Studio 2005 after installing these tools, you will notice that a new set of templates is available (but only for Visual Basic and Visual C#):

There are four new templates:

  • WinFX Windows Application: To create an application with an Avalon user interface
  • WinFX XAML Browser Application: To create an application with a Windows Presentation Foundation user interface that runs in the browser within a sandbox
  • WinFX Service Library: To create a library that contains the definition and implementation of a WinFX service
  • WinFX Custom Control Library: To create controls for use in Avalon applications

In this article, you will create a simple WinFX Windows Application, called XAMLCalculator. This application will have the following characteristics:

  • Handles only integer operands
  • Supports simple arithmetical operation (add, substract, multiply, divide)
  • Supports erasing the last typed digit
  • Supports changing the sign of the operand

Because this application is provided only to demonstrate the development of WPF applications, you want to keep it simple. Therefore, any other features would probably divert the attention from the focus of this article. While doing this, you will concentrate on two aspects of development:

  • Designing the user interface of the application
  • Implementing the business logic for the application

Building the WinFX Windows Application

To start, launch Visual Studio 2005, go to New > Project and select Other Languages > Visual C# > Windows (WinFX) and choose the WinFX Windows Application template. Type in the name XAMLCalculator and press OK. After that, you will see the following window:

'Cider' has created an empty window for you, called XAMLCalculator. At this point, there are two opened files: Window1.xaml and Window1.xaml.cs. When the first one is selected, you can choose to see it in two different ways: in Designer (where you can see the designed user interface) or in the XAML editor (where you can see and edit the XAML code). Additionally, if you select to see the Source, you will be shown the Window1.xaml.cs file. So, what is this xaml.cs file? It is a C# source file that implements the business logic for your interface. For instance, you will write XAML code adding buttons and a textbox to the window, but you will put the code that handles the events for these controls in a C# file.

The first thing I always do when creating a new project is to change the default names for the files and classes that the wizard writes. In this case, I have changed Window1.xaml to XAMLCalculatorWindow.xaml and the name of the Window1 class to CalculatorWindow. But, that's not enough. In the XAMLCalculatorWindow.xaml, the root element, Window, has an attribute that specifies what class is instantiating this window:

<Window x:Class="XAMLCalculator.Window1 "
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="XAMLCalculator" Height="268" Width="280"
   Background="#FFFFFFFF">

That must be manually changed to:

<Window x:Class="XAMLCalculator.CalculatorWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="XAMLCalculator" Height="268" Width="280"
   Background="#FFFFFFFF">

Additionally, there is a MyApp.xaml file with a paired MyApp.xaml.cs file. Although the window represents the main visual component, it is part of an application, and that's what these two files define. If you open the MyApp.xaml file in the designer, it will be empty and you cannot add controls to it, but you can edit the XAML code. And that's what you need: the application root element has an attribute that specifies the startup URI:

<Application x:Class="XAMLCalculator.MyApp"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   StartupUri="Window1.xaml"
   >
   <Application.Resources>
   </Application.Resources>
</Application>

And this also has to be manually changed to

StartupUri="XAMLCalculatorWindow.xaml"

Designing the User Interface

After these initially changes, you will start adding a set of buttons and a text box to the window. Finally, it should look like this (notice that I also played a little with the background colors of the window and the text box):

At this point, if you take a look in the XAML editor, you can see the code:

<Window x:Class="XAMLCalculator.CalculatorWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="XAMLCalculator" Height="268" Width="280"
                          Background="#FFFFFFEE">
   <Grid Height="229" Width="267">
      <TextBox VerticalAlignment="Top" HorizontalAlignment="Left"
               Grid.Column="0" Grid.ColumnSpan="1"
               Grid.Row="0" Grid.RowSpan="1" Margin="17,29,0,0"
               Width="243" Height="25" Name="textBox1"
               Background="#FFEEEEEE" FlowDirection="LeftToRight"
               TextAlignment="Right" IsReadOnly="True"></TextBox>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="17,77,0,0"
              Width="35" Height="23" Name="button7">7</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="69,77,0,0"
              Width="35" Height="23" Name="button8">8</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="121,77,0,0"
              Width="35" Height="23" Name="button9">9</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="173,77,0,0"
              Width="35" Height="23" Name="buttonDiv">/</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="225,77,0,0"
              Width="35" Height="23" Name="buttonBack">Back</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="17,111,0,0"
              Width="35" Height="23" Name="button4">4</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="69,111,0,0"
              Width="35" Height="23" Name="button5">5</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="121,111,0,0"
              Width="35" Height="23" Name="button6">6</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="173,111,0,0"
              Width="35" Height="23" Name="buttonMul">*</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="225,111,0,0"
              Width="35" Height="23" Name="buttonClear">C</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="17,145,0,0"
              Width="35" Height="23" Name="button1">1</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="69,145,0,0"
              Width="35" Height="23" Name="button2">2</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="121,145,0,0"
              Width="35" Height="23" Name="button3">3</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="173,145,0,0"
              Width="35" Height="23" Name="buttonSub">-</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="17,179,0,0"
              Width="35" Height="23" Name="button0">0</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="69,179,0,0"
              Width="35" Height="23" Name="buttonSign">+/-</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="121,179,0,0"
              Width="35" Height="23" Name="buttonEqual">=</Buton>
      <Button VerticalAlignment="Top" HorizontalAlignment="Left"
              Grid.Column="0" Grid.ColumnSpan="1"
              Grid.Row="0" Grid.RowSpan="1" Margin="173,179,0,0"
              Width="35" Height="23" Name="buttonAdd">+</Buton>
   </Grid>
</Window>

In the beginning, you might find it a little bit harder to work with the designer. Because it's still a beta release, it might show some problems, including (as in my case) the impossibility of typing something in the XAML editor (although the cut/delete or pasting operations work fine). (WPF Designer (Cider) Forum is the dedicated forum where you can report possible bugs).

At this point, you can compile and run the application. But, as you press the buttons, nothing happens because you have not yet implemented any event handling. Thus, the next step is to take care of the business logic for your simple calculator.

Implementing the Business Logic

You need to handle the click event for all the buttons you have placed into the main window of the application. For that, you first will add a handler for each button in the C# source file (XAMLCalculatorWindow.xaml.cs), with the following prototype:

void OnButtonClick(object sender, RoutedEventArgs args)
{
}

But, you will name the handlers different for each button (like OnButton0Click to OnButton9Click, OnButtonEqualClick, and so forth).

The first parameter of the handler indicates the sender of the event, and the second contains all state information and event data associated with a routed event. So, what is a routed event? It is an event routed between the XAML user interface and the managed-code runtime, in a mechanism called "routed events."

Next, you have to add a Click attribute for each Button, indicating the handler from XMLCalculator.CalculatorWindow that will handle the event. Here is how it looks for button 0:

<Button Click="OnButton0Click" VerticalAlignment="Top"
        HorizontalAlignment="Left" Grid.Column="0"
        Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="1"
        Margin="17,179,0,0" Width="35" Height="23"
        Name="button0">0</Button>

With all this in place, you can start coding the business logic. Because this is beyond the scope of this article, I will not cover it here, but you can look at it by downloading the sample application provided with this article. If you compile and run that application, the window looks like this:

Conclusion

And with that, you have finished writing your first WinFX Windows Application. It's not something spectacular, but it proves the concept of separation the user interface from the implementation. In future articles, you will see how to write more complex applications with WPF and I will introduce the Expression Interactive Designer (formerly code-named 'Acrylic').



About the Author

Marius Bancila

Marius Bancila is a Microsoft MVP for VC++. He works as a software developer for a Norwegian-based company. He is mainly focused on building desktop applications with MFC and VC#. He keeps a blog at www.mariusbancila.ro/blog, focused on Windows programming. He is the co-founder of codexpert.ro, a community for Romanian C++/VC++ programmers.

Downloads

Comments

  • Express Editions

    Posted by logan on 11/21/2006 12:25am

    Cider components don't work with Express Editions. You need VS 2005 Standard or higher editions.

    Reply
  • Kool

    Posted by logan on 06/06/2006 09:05am

    Maybe I didn't read it properly but it looks to me that the separation of business logic from designing the UI is pretty similar to a WinForm app? Design the UI in a fancy editor and set the event hanlders. Don't we do the same thing in a WinForm app? Regards.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Not long ago, security was viewed as one of the biggest obstacles to widespread adoption of cloud-based deployments for enterprise software solutions. However, the combination of advancing technology and an increasing variety of threats that companies must guard against is rapidly turning the tide. Cloud vendors typically offer a much higher level of data center and virtual system security than most organizations can or will build out on their own. Read this white paper to learn the five ways that cloud …

  • For the third consecutive year, Neustar surveyed hundreds of companies on distributed denial of service (DDoS) attacks. Neustar's survey reveals evidence that the DDoS attack landscape is changing. The number of companies attacked is up, but attack duration is down. Larger attacks are more common, but most attacks are still less than 1 Gbps. More than half of attacked companies reported theft of funds, data or intellectual property. Read the full report to learn how DDoS attacks have evolved in both strategy …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds