Using XAML with C++

User interface development with C++ for Windows applications can be a challenging experience. When Visual Basic first appeared all those years ago, developers flocked to it, in part, because building a user interface in it was so much more productive than building the equivalent UI using C++ at that time, and C++ has never really caught up since.

Over recent years, with Microsoft moving away from WinForms, and the rise of declarative interface design with XAML, building a flexible yet powerful user interface has never been easier. The functionality offered by XAML based UI technologies is impressive, with data binding, in particular, being a genuine productivity enhancement.

Meanwhile, C++ developers have been left further and further behind, with the mainstream interface development typically found in the work being done by game studios and some in-house Microsoft product teams. Starting with VS2012, the power and flexibility of the XAML based user interface design is now available for C++ developers, making C++ a legitimate choice for business applications.

Tip

C++ can use XAML only when creating Universal Windows Platform (UWP) applications. You cannot use this combination together to create traditional Windows desktop applications.

It's not just business applications that benefit though. Developers of DirectX applications can use XAML to render interface elements, compositing them with their application's DirectX output. For game developers, this might be things such as application menus, score displays, and so on. Alternatively, you can have XAML-based applications interspersed with portions of DirectX code in them, allowing developers of applications with a need for 3D imaging, such as medical or geospatial systems, to mix and match DirectX and XAML as required.

The choice and flexibility is up to you. For this recipe, you'll create a simple XAML-based interface with data binding to see how it all fits together.

Getting ready

Ensure that you are on a Windows 10 machine. UWP app development is not supported on prior versions of Windows.

Start a premium version of VS2015 or use VS2015 Community, and you will be ready to go.

Tip

As noted elsewhere, keep your copy of Visual Studio current, and be sure the latest updates are applied. For this recipe, ensure you have applied Update 2 or newer.

How to do it...

Create the app by following these steps:

  1. Create a new Blank App (Universal Windows) project by navigating to Visual C++ | Windows | Universal, and name it CppDataBinding.

    Tip

    For this recipe, the project name is important, as it is referenced below in the sample code. If you pick a different name, be sure to update the code accordingly!

  2. Open the MainPage.xaml file, and add the following code inside the <Grid> element:
    <Border BorderBrush="LightBlue" BorderThickness="4" CornerRadius="20" Margin="5">
      <StackPanel Margin="5">
        <TextBlock Text="Red level" Margin="5" />
        <Slider x:Name="redLevelSlider" Minimum="0" Maximum="255" Value="{Binding Path=RedValue, Mode=TwoWay} "Margin="5" Width="255" HorizontalAlignment="Left" />
        <TextBlock Text="Numeric value:" Margin="5"/>
        <TextBox x:Name="tbValueConverterDataBound" Text="{Binding Path=RedValue, Mode=TwoWay} "Margin="5" Width="150" HorizontalAlignment="Left"/>
      </StackPanel>
    </Border>
  3. For the data binding to work, you will need an object to bind to. Add a new header file to your project, and call it MyColor.h. The header can be added by right-clicking on your project name, selecting Add | New Item from the context menu, and then choosing Header File. Be sure to hold off compiling the code until you get to Step 9, as compiling before that will result in compiler errors.
  4. Enter the following code as the content of the MyColor.h source file:
    #pragma once
    #include "pch.h"
    using namespace Platform;
    using namespace Windows::UI::Xaml::Data;
    namespace CppDataBinding
    {
      [Bindable]
      public ref class MyColor sealed : INotifyPropertyChanged
      {
        public:
        MyColor(void);
        virtual ~MyColor(void);
        virtual event PropertyChangedEventHandler^ PropertyChanged;
        property String^ RedValue
        {
          String^ get() { return _redValue; }
          void set(String^ value)
          {
            _redValue = value;
            RaisePropertyChanged("RedValue");
          }
        }
        protected:
        void RaisePropertyChanged(String^ name);
        private:
        String^ _redValue;
      };
    }
  5. Next, we will need to add a new C++ file named MyColor.cpp. Similar to the header file, right-click on the project, and select Add | New Item—only this time, choose C++ File. Once it has been created, enter the following code as its content:
    #include "pch.h"
    #include "MyColor.h"
    using namespace CppDataBinding;
    using namespace Windows::UI::Xaml::Data;
    MyColor::MyColor(void) {}
    MyColor::~MyColor(void) {}
    void MyColor::RaisePropertyChanged(String^ name)
    {
      PropertyChanged(this, ref new PropertyChangedEventArgs(name));
    }
  6. Now go to the MainPage.xaml.h file, and add the MyColor.h file to the #include list.
  7. While in the MainPage.xaml.h file, go to the public members of the MainPage class, and add the following line of code that is highlighted:
    public:
      MainPage();
      property MyColor^ _myColor;
  8. Next, navigate to the code-behind file for the MainPage class (MainPage.xaml.cpp), and add the following highlighted lines of code to the constructor:
    MainPage::MainPage()
    {
      InitializeComponent();
      _myColor = ref new MyColor();
      this->DataContext = _myColor;
    }
  9. Compile and run the application. You should see a screen similar to the following screenshot. As you enter values in the text field or move the slider, the two fields should remain in sync, as shown in the following screenshot:
    How to do it...

How it works...

The C++ code you have been writing is C++/CX, an extension of normal C++. You can still use normal C++ (without extensions) if you prefer, but it will mean dealing with the IInspectable interface and writing more COM code than would otherwise be the case.

The ref keyword you used for creating an instance of the MyColor class tells the compiler that you are using a Windows runtime object. The carat (^) symbol on variable declarations is a reference counting smart pointer to a Windows runtime object. It is similar to a normal pointer, but performs reference counting and automatic cleanup of resources when the last reference is cleared.

Data binding in C++ kicks into action when you insert the [Bindable] attribute into a class. When the compiler sees this, it automatically generates code in a file called xamltypeinfo.g.cpp, which implements the appropriate binding behaviors for interacting with the XAML markup.

In your code, you implemented the INotifyPropertyChanged interface. This was done so that you could use the two-way binding between the data class and the UI elements on the screen. The implementation of the interface should look familiar to anyone who has worked with the INotifyPropertyChanged interface in either WPF or Silverlight.

If you were compiling the code after each step of the recipe, you may have seen a few compiler errors, some of which might have not made much sense.

If you compiled the application after Step 5, you may have seen a number of errors in the XamlTypeInfo.g.cpp file.

This occurs because of the way the compiler handles the [Bindable] attribute and the generation of the code. The generated code not only includes the .h files from the XAML pages in the application, but also includes generated code for any types that are bindable. This means that if you have a bindable type, but no references to it in any of the .xaml.h files, you will have undeclared identifier errors. Adding the #include statement for the bindable class' header file as you did in Step 6 fixes this compiler error.

There's more…

Microsoft continues to add functionality to the XAML toolset, and with Update 2, there are some additional tools available to us when the project is compiled in Debug mode beyond the frame rate counters.

The following screenshot shows the expanded XAML toolbar:

There's more…

The toolbar provides three different functions (from left to right): Go to Live Visual Tree, Enable selection, and Display layout adorners. The first opens a new dialog in Visual Studio that lists the hierarchical relationship of the XAML controls present in your app, and provides a two-way connection between this dialog window and the control(s) on your application. From the application side, you can click on a particular control and locate it within the hierarchy, or you can pick an element from the hierarchy and see it highlighted in your application.

Enable selection is a toggle that lets you highlight and select various XAML elements for inspection. Finally, Display layout adorners is a toggle that will show the various borders of the XAML elements, as shown in the following screenshot:

There's more…

These tools provide another way to examine your application's appearance, and to troubleshoot any layout issues you may be experiencing.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.246.193