2012

Volume 27

XAML and C++ - Introducing C++/CX and XAML

By Andy Rich | 2012

Code First is great for designing  a fast sorting algorithm, but it isn’t necessarily the best way to make a good-looking UI, and the UI technology provided by Microsoft for C++ developers has reflected this preference. The last significant upgrade to Microsoft UI technology for C++, released in 2008, was a new set of MFC controls that provided styled Ribbon controls. Before that was Windows Forms, a Microsoft .NET Framework-based UI technology first released with Visual Studio .NET in February 2002. While powerful, both of these technologies were primarily focused on the underlying code that created the UI elements and demanded tight coupling of data and the UI.

In recent years, C# and Visual Basic developers have enjoyed significant upgrades to their UI technology in the form of XAML-based UI frameworks (Windows Presentation Foundation, or WPF, and Silverlight). These frameworks brought developers new options in UI design, giving them the freedom to code their algorithms without worrying about how the UI would be presented, and the freedom to design their UI without worrying about the code behind it. At last, with Windows 8, C++ developers can take advantage of a modern, XAML-based UI framework to build applications for Windows 8.

Why XAML?

XAML is an XML-based markup language that allows you to define the look of your application without needing to understand how the UI is built in code. The Windows Runtime (WinRT) parses this information at run time, constructs the appropriate control classes and builds the UI tree. Your code can manipulate these objects and, when authored correctly, the look and feel of the UI can be significantly altered without touching the codebehind at all. This facilitates a division of labor between a developer who works on the code behind the scenes and a UI designer who focuses on the look and feel of the application itself.

Visual Studio 2012 also is tightly integrated with Blend, a power­ful designer tool specifically optimized for working with XAML and HTML. Blend provides more WYSIWYG control (including animation design) and exposes more properties on XAML objects than the Visual Studio integrated designer.

Why C++/CX?

Developers have a range of technologies to choose from when writing a Windows Store app: HTML and JavaScript, C# or Visual Basic with XAML, and C++. In C++, you can build apps with C++/CX and XAML or DirectX, or a combination of both. In addition, you can create an application that’s a hybrid of these technologies, such as writing a component in C++/CX that’s then used from a Windows Store app built with JavaScript/HTML.

There are a number of reasons for you to choose C++ for writing a Windows Store app. First, the C++/CX binding to the Windows Runtime is 100 percent native and reference-counted. This means there’s very little overhead. Second, C++ has the ability to leverage existing libraries (such as Boost). Finally, C++ supports native Direct3D and Direct2D surfaces inside Windows Store apps, which enables you to build games and other graphically intensive applications with great performance. Having low overhead and high performance doesn’t only mean that your application runs faster; it can also be leaner, using fewer instructions to accomplish the same tasks, which reduces power consumption and gives your users better battery life.

Hello World from C++/CX and XAML

Visual Studio 2012 provides a number of templates that demonstrate advanced features of Windows Store apps. The Grid template is a feature-packed application with multiple views, support for landscape and portrait transitions, advanced data binding, and suspend and resume capabilities. However, it isn’t very suitable for demonstrating the basics. Instead, create a new C++ Windows Store app using the Blank App (XAML) template.

Once the application is created, find MainPage.xaml in Solution Explorer and open it. It opens for editing in the integrated XAML designer, which is split into two panes: the Design view shows a rendering of the UI, and the XAML view shows the code. Updating either pane updates the other as well. This gives you the freedom to drag controls for ease of editing or to precisely control the layout by editing the code.

Open the toolbox, expand Common XAML Controls and drag a TextBlock control onto the design surface. Open the Properties window, and you’ll find options for styling this instance of the TextBlock control. In the Name field, name the TextBlock “myText.” This correlates to the x:Name attribute in XAML. This attribute allows you to refer to the TextBlock by name, both elsewhere in the XAML file and in the codebehind. And, because this is the only control on the page, you might as well make it very large: expand the Text category and change the font size to 72px. The end result should resemble Figure 1. You’ll notice that as you make these changes in the property inspector, the XAML markup is also updated.

TextBlock Control and Related XAML
Figure 1 TextBlock Control and Related XAML

Next, drag a Button control from the toolbox and put it to the left of the TextBlock. In the Properties window, view the available events for the Button control by clicking the lightning-bolt icon to the right of the Name field, and then double-click the field for the Click event. Visual Studio automatically generates an appropriate callback and switches the view to the codebehind for this event. In the XAML source view, the generated tag should look something like the following:

<Button Click="Button_Click_1" />

You could accomplish the same thing in code by adding the Click= attribute for the XAML tag and then providing a name or allowing autocomplete to select one for you. Either way, you can right-click the event and choose Navigate To Event Handler to navigate to the codebehind.

Now add the following code to the callback:

this->myText->Text =
    "Hello World from XAML!";

Build and run the application to verify that when you click the button, the callback modifies the text in the TextBlock (Figure 2).

Updated TextBlock
Figure 2 Updated TextBlock

A lot goes on behind the scenes here, so I want to spend some time deconstructing the magic that makes this happen.

What Is C++/CX?

C++/CX is the language extension that provides interoperability between native C++ and the Windows Runtime. It’s a fully native binding that enables you to define, instantiate and use objects in the runtime while still providing access to native C++ functionality and syntax with which you’re familiar. Figure 3 lists the basic concepts. (Although C++/CX is similar in many ways to the C++/Common Language Infrastructure, or CLI, syntax, it’s a separate and wholly native language extension.)

Figure 3 C++/CX Concepts

Concept Description
interface class An abstract declaration of the methods that an object implementing the interface will support calls into.
ref class C++/CX keyword that’s used to declare a reference-counted class in the Windows Runtime that’s used for implementing interfaces.
^ Called a “hat” or “handle,” this is a smart pointer for use with ref classes and interfaces; it automatically increments and decrements reference counts appropriately.
ref new Expression that “activates” (constructs) a WinRT class. 
default namespace Contains fundamental type definitions (uint32, float64) that map to WinRT types.
Platform namespace Contains type definitions that provide the basic interoperability model with the Windows Runtime (Object^, String^).
Property A pseudo-field on a class; it’s composed of a getter function and an optional setter function and behaves like a field. (For example, a TextBlock object has a Text property.)

Partial Classes and XAML Code Generation In Solution Explorer, navigate to MainPage.xaml.h, which contains a partial definition of the MainPage XAML class:

public ref class MainPage sealed
{
public:
  MainPage();
protected:
  virtual void OnNavigatedTo(
    Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
  void Button_Click_1(
    Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
};

This is the portion of the definition that you can edit and modify (for example, if you want to add some data members to the MainPage class). Note that the declaration of the Button_Click_1 event handler was inserted into this class definition by Visual Studio when you double-clicked the Click event earlier.

Right-click on the class name MainPage and choose Go To Definition. You should see two results: the definition in MainPage.xaml.h and a partial definition in MainPage.g.h. The second definition is generated during a build when the XAML compiler parses MainPage.xaml and generates MainPage.g.h. MainPage.xaml.cpp includes MainPage.xaml.h, which in turn includes this generated file. These class definitions are combined to produce the final class. This technique permits both users and the code generator to inject information into the class definition.

Navigate to the partial definition of MainPage found in MainPage.g.h:

partial ref class MainPage : public ::Windows::UI::Xaml::Controls::Page,
  public ::Windows::UI::Xaml::Markup::IComponentConnector
{
public:
  void InitializeComponent();
  virtual void Connect(int connectionId, ::Platform::Object^ target);
private:
  bool _contentLoaded;
  private: ::Windows::UI::Xaml::Controls::TextBlock^ myText;
};

You can see that in this generated file, the x:Name=“myText” attribute on the TextBlock has caused the XAML compiler to generate a class member named myText. Here you can also observe that MainPage inherits from the Windows XAML base class Page and implements the interface IComponentConnector. (IComponent­Connector and its associated method Connect are what wire up the Click event to the Button_Click_1 callback.)

Data Binding in C++/CX Data binding is a powerful concept that enables you to easily wire up code and data to your UI. It also enables high-level design patterns such as Model-View-ViewModel (MVVM) that provide excellent abstraction between data, code and the UI.

In C++/CX, you can enable a class to be data-bound in a number of ways:

  • Attribute the class with the Bindable attribute
  • Implement the ICustomPropertyProvider interface
  • Implement the IMap<String^, Object^> interface 

I’ll focus on the Bindable attribute, but I’ve mentioned the other interfaces because in some scenarios they’re more appropriate. In particular, the Bindable attribute generates appropriate data- binding information only if the data-bound class is marked public. Whenever you want a private class to be bindable, you need to implement one of the other interfaces listed.

In your application, add a new class by right-clicking the project and choosing Add, Class to bring up the Add Class Wizard. There’s no option for a C++/CX class (which is what you need), so add a native class, naming it Person. Visual Studio should generate a Person.h and Person.cpp class and add them to your project.

The Person class needs several modifications (demonstrated in Figure 4):

Figure 4 Definition of the Person Class

// person.h
#pragma once
namespace App12 {
  [Windows::UI::Xaml::Data::Bindable]
  public ref class Person sealed
  {
  public:
    Person(void);
    property Platform::String^ Name;
    property Platform::String^ Phone;
  };
}
// person.cpp
#include "pch.h"
#include "person.h"
using namespace App12;
Person::Person(void)
{
  Name = "Maria Anders";
  Phone = "030-0074321";
}
  • The class definition is changed from class to ref class.
  • The ref class is marked as public and sealed. “Public” is necessary for the XAML compiler to find this class and generate data-binding information. Also, C++/CX doesn’t support public unsealed classes without a base class, so the class must be sealed.
  • The destructor ~Person(void) is removed because no destructor is necessary for this class.
  • The class is moved into the namespace used by the application (in the example shown in Figure 4, the namespace is “App12,” but this will vary based on the name you gave your project). For the Bindable attribute to work (and to satisfy WinRT metadata rules), the class must be in a namespace.
  • The class is attributed with [Windows::UI::Xaml::Data::Bin­dable]. This attribute indicates to the XAML compiler that it should generate data-binding information for the class.
  • Two properties of type Platform::String^: Name and Phone are added. (Only properties can be data-bound.)

Now, in MainPage.xaml, add a second TextBlock below the first and style it similarly. In the XAML, change the Text attribute of the two TextBlocks to Text=“{Binding Name}” and Text=“{Binding Phone}”, respectively. This tells the UI to find properties named Name and Phone on the data-bound object and apply them to the Text field of the class. The XAML should look similar to Figure 5. (When the Text attributes are changed to be data-bound, they no longer have contents when they’re shown in the designer; this is expected.)

Data Binding in XAML
Figure 5 Data Binding in XAML

Next, in MainPage.xaml.h, include Person.h and add a private datamember of type Person^ to the MainPage class. Name it m_Person. Finally, in MainPage.xaml.cpp, in the OnNavigatedTo method, add the following code:

m_Person = ref new Person;
this->DataContext = m_Person;

The XAML runtime invokes the OnNavigatedTo method just before this page is displayed on the screen, so it’s an appropriate place to set up this datacontext. This code will create a new instance of the Person class and bind it to your MainPage object. Run the application again, and you should see that the Name and Phone properties have been applied to the TextBlock Text attributes.

The data-binding infrastructure also provides for the data-bound objects to be notified if the property’s contents change. Change the Button_Click_1 method to the following code:

this->m_Person->Name = "Anders, Maria";

If you run the application again and click the button, you’ll see that the TextBlock contents do not change. For these contents to be updated, the Person class needs to implement the INotify­PropertyChanged interface.

INotifyPropertyChanged has one item in it: an event named PropertyChanged, of type PropertyChangedEventHandler^. The Name property also needs to be changed from a trivial property to a fully defined property (including a user-provided backing store) to support firing this event when the property is modified. In addition, I added a convenience function named NotifyPropertyChanged that fires this event when it’s called. This is a commonplace refactoring, because multiple properties often require notification. The implementation is shown in Figure 6. (This example only provides for the Name property to be notifiable. A similar change would need to be made for the Phone property.)

Figure 6 Person Class with Notifiable Name Property

// person.h
#pragma once
namespace App12 {
  namespace WUXD = Windows::UI::Xaml::Data;
  [WUXD::Bindable]
  public ref class Person sealed : WUXD::INotifyPropertyChanged
  {
  public:
    Person(void);
    property Platform::String^ Name {
      Platform::String^ get();
      void set(Platform::String^ value);
    }
    property Platform::String^ Phone;
    virtual event WUXD::PropertyChangedEventHandler^ PropertyChanged;
  private:
    void NotifyPropertyChanged(Platform::String^ prop);
    Platform::String^ m_Name;
  };
}
// person.cpp
#include "pch.h"
#include "person.h"
using namespace App12;
using namespace Platform;
using namespace WUXD;
Person::Person(void)
{
  Name = "Maria Anders";
  Phone = "030-0074321";
}
String^ Person::Name::get(){ return m_Name; }
void Person::Name::set(String^ value) {
  if(m_Name != value) {
    m_Name = value;
    NotifyPropertyChanged("Name");
  }
}
void Person::NotifyPropertyChanged(String^ prop) {
  PropertyChangedEventArgs^ args = 
    ref new PropertyChangedEventArgs(prop);
  PropertyChanged(this, args);
}

Running the application again with the INotifyPropertyChanged modifications made should result in the name change when the button is clicked.

ItemsControls and Collections in C++/CX and XAML

XAML provides rich UI controls, including controls that can data bind to a collection of objects. These are collectively referred to as ItemsControls. I’ll focus on one in particular, called ListView.

Open MainPage.xaml and delete the contents of the root Grid object, replacing it with just a ListView class. Name that class myListView, as shown here:

<!-- ListView inside MainPage -->
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">*
  <ListView x:Name="myListView" />
</Grid>

Collections in C++/CX The Windows Runtime does not provide collection classes; it only provides interfaces for the collections. Each projection (JavaScript, C#/Visual Basic and C++/CX) is responsible for providing its own collection classes. In C++/CX, these implementations are found in the collection.h header (which is already included in the pch.h of the Blank application template). There are two major collection classes defined in the Platform::Collections namespace: Platform::Collections::Vector<T> for representing lists of data, and Platform::Collections::Map<T,U> for representing dictionaries. ItemsControls generally expect an iterable list of objects, so Vector<T> is appropriate in this scenario.

In MainPage.xaml.cpp, change the OnNavigatedTo method to “ref new” a Vector<Person^> and fill it with several Person classes. Then assign it to the ItemsSource property of myListView:

void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
  (void) e; // Unused parameter
  auto vec =
    ref new Platform::Collections::Vector<Person^>;
  vec->Append(ref
    new Person("Maria Anders","030-0074321"));
  vec->Append(ref new Person("Ana Trujillo","(5) 555-4729"));
  // etc. ...
  myListView->ItemsSource = vec;
}

Styling the ListView Finally, we need to tell the ListView how to style each individual element. The ListView will then iterate over its ItemsSource and, for each element in the collection, generate the appropriate UI and bind its DataContext to that element. To style the ListView, you must define its ItemTemplate, as shown in Figure 7. Note that the Text properties inside the template have the data bindings appropriate for a Person object.

Figure 7 ListView Inside MainPage with Styled ItemTemplate

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
  <ListView x:Name="myListView">
    <ListView.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Vertical">
          <TextBlock Text="{Binding Name}" FontSize="20" />
          <TextBlock Text="{Binding Phone}" FontSize="12" />
        </StackPanel>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</Grid>

When you build and run this application, it should resemble Figure 8.

The Finished ListView
Figure 8 The Finished ListView

 

Find Out More

References on XAML for Windows 8 and C++/CX are somewhat scarce at the moment. To learn more about XAML, I recommend looking for references that talk about XAML in Silverlight, as many of the same concepts apply and many controls are named similarly or the same and have the same functionality. The codebehind for these references will be C#, so some translation or interpretation is necessary. This is chiefly a mechanical operation, but where you run into functionality that’s represented by the .NET Base Class Library, you need to look to the C Runtime Libraries, Standard Template Library or other C++ libraries (or the Windows Runtime) to accomplish these tasks. Fortunately, all of these libraries play nicely with C++/CX. 

Other great resources are the templates available in Visual Studio 2012 for creating Windows Store apps, in particular the Grid App and Split App. These templates demonstrate many advanced features of a well-made application, and deciphering their secrets can lead to greater understanding of the underlying frameworks.

Finally, I recommend that you look at project “Hilo,” a large-scale application written using C++ and XAML. The code and documentation for this application can be found at hilo.codeplex.com. This project was developed by the Microsoft patterns & practices team and demonstrates modern, standard C++; the porting of existing C++ libraries so that they can be used in Windows Store applications; and many best practices when using C++/CX.

I hope I’ve given you a glimpse at what you can do with C++/CX and with XAML, but this is just the surface. As with any new technology, you can expect to spend many late nights browsing documentation and forums and with your nose buried in technical books. But the power and capability of C++/CX and XAML are worth learning more about. They will enable you to write rich, fast applications in far less time.


Andy Rich is a software development engineer at Microsoft and has spent the last nine years testing the C++ front-end compiler. Most recently, he was one of the primary testers of the C++/CX language extensions and worked closely with the XAML team in testing the combined XAML/C++ scenario.

Thanks to the following technical experts for reviewing this article: Tim Heuer, Marian Luparu and Tarek Madkour