Tag Archives: XAML

Writing C++ /CX code to generate XAML UI

Quite often I get asked a very simple question: Can I skip using XAML for creating the User Interface for my app and use C++ instead? The answer is yes you can, but the bigger question is: why do you want to go down that route? I guess, to each his/her own. I must say, I do not relish the idea of writing so much C++ code. Anyways, here is our sample.

Our example today relies on the very basic Blank Metro app template that ships along with Visual Studio.

  1. Create a solution based on the Blank Metro app template and in the MainPage.xaml, delete the Grid section.
  2. Add a new function to the MainPage.xaml.h file, say, CreateUI. This function takes no parameters and returns void.
  3. In the MainPage.xaml.cpp, add the call to CreateUI inside the MainPage constructor, just after the InitializeComponent function call.
  4. Now for the cool part.
  5. For our sample today, we will create a Grid and add a TextBlock with the message Hello World. This is our pure-code only equivalent of the canonical Hello World samples. Smile
  6. Here is the full listing of the function
    auto grid = ref new Grid();
    auto gridBackground = ref new SolidColorBrush();
    gridBackground->Color = Windows::UI::Colors::Black;

    this->Content = grid;

    auto helloText = ref new TextBlock();
    helloText->Text = "Hello World";
    helloText->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Center;
    helloText->VerticalAlignment = Windows::UI::Xaml::VerticalAlignment::Center;

    helloText->FontSize = 30;
    helloText->FontWeight = Windows::UI::Text::FontWeights::Bold;
    helloText->FontStyle = Windows::UI::Text::FontStyle::Oblique;
    auto fontFamily = ref new Windows::UI::Xaml::Media::FontFamily("Segoe UI");
    helloText->FontFamily = fontFamily;

    auto textForeground = ref new SolidColorBrush();
    textForeground->Color = Windows::UI::Colors::Green;
    helloText->Foreground = textForeground;

    grid->Children->Append(helloText);

Enjoy!!

Announcement: Book on C++ /Cx and Metro style app development

Hi

I am happy to announce an upcoming book on C++ /Cx and Metro style app development. This book is currently in the works and will be published by Microsoft Press. I present a brief list of topics that are covered in the book.

1. Windows Runtime, WRL and writing apps using WRL.

2. C++ /Cx and C++ 11 features.

3. XAML and C++ /Cx (includes discussion on XAML plus DirectX)

4. Incorporating C++ AMP in Metro style apps.

5. Building WinRT components using C++ /Cx

6. Unit Testing support for C++ in VS 2011.

C++ 11 is new; C++ /Cx is new and so is WinRT. I am super excited to work on these technologies and author a book. Stay tuned for more!!

Enjoy!

Hello World from XAML and C++ /CX

We have previously explored how to write a Hello World console application using C++ /CX. Today we will develop a Hello World Application using XAML. Our Hello World app will have a simple XAML Button. Clicking the Button displays the text, Hello World on screen. Smile

As is the case, here is our MainPage.xaml

<Page
    x:Class="FirstApp.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:FirstApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Button x:Name="myBtn" Width="200" Height="120" Content="Click Me" Click="myBtn_Click_1"/>
        <TextBlock x:Name="Hello" TextWrapping="Wrap" Width="200" Height="50" FontSize="20"/>
    </Grid>
</Page>

Now the actual “code behind” for MainPage.xaml. Visual Studio 2011 does an excellent job of generating the initial “ref class” for MainPage. Here is the full listing for MainPage.xaml.h

//
// MainPage.xaml.h
// Declaration of the MainPage class.
//

#pragma once

#include "MainPage.g.h"

namespace FirstApp
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public ref class MainPage sealed
    {
    public:
        MainPage();

    protected:
        virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
    private:
        void myBtn_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
    };
}

Finally, the full implementation of MainPage ref class, MainPage.xaml.cpp

//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//

#include "pch.h"
#include "MainPage.xaml.h"

using namespace FirstApp;

using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

MainPage::MainPage()
{
    InitializeComponent();
}

/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.  The Parameter
/// property is typically used to configure the page.</param>
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
    (void) e;    // Unused parameter
}


void FirstApp::MainPage::myBtn_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    Hello->Text = "Hello World";
}

Finally the output on screen

Hello World

Enjoy!!!

Implementing an IValueConverter in C++ /Cx for Data Binding

To create a value converter, we create a class that implements the IValueConverter interface and then implement the Convert and (optionally) the ConvertBack methods. Converters can change data from one type to another, translate data based on cultural info, or modify other aspects of the presentation.

In our sample today, we create a basic two way grade converter based on the DataBinding Metro SDK Sample App. Unlike most samples, this example shows a Two Way implementation of the IValueConverter interface and binding.

Our XAML markup is fairly simple and straight forward.

This is the MainPage.xaml

<Page
    x:Class="DataBinding.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DataBinding"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid x:Name="Input" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <StackPanel>
                <TextBlock Style="{StaticResource BasicTextStyle}" TextWrapping="Wrap" Text="The demonstration below shows how a custom value converter (an IValueConverter implementation) is used to control how data is displayed." />                
            </StackPanel>
        </Grid>
        
        <Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1">
            <StackPanel>
                <Border BorderBrush="LightBlue" BorderThickness="4" CornerRadius="20" Margin="5">
                    <StackPanel Margin="5">
                        <!-- Add converter as a resource to reference it from a Binding. -->
                        <StackPanel.Resources>
                            <local:DataConverter x:Key="GradeConverter"/>
                        </StackPanel.Resources>
                        <TextBlock Style="{StaticResource BasicTextStyle}" Text="Percent grade:" Margin="5" />
                        <Slider x:Name="sliderValueConverter" Minimum="1" Maximum="100" Value="70" Margin="5"/>
                        <TextBlock Style="{StaticResource BasicTextStyle}" Text="Letter grade:" Margin="5"/>
                        <TextBox x:Name="tbValueConverterDataBound" 
                                Text="{Binding ElementName=sliderValueConverter, Path=Value, Mode=TwoWay, 
                                              Converter={StaticResource GradeConverter}}" 
                                 Margin="5" Width="150"/>
                    </StackPanel>
                </Border>
            </StackPanel>
        </Grid>  
    </Grid>
</Page>

Next, we create a local C++ class, named DataConverter. This is the class that implements the IValueConverter interface. The IValueConverter interface is found in the Windows::UI::Xaml::Data namespace.

Here is the full listing of the DataConverter.h

// This class provides a simple IValueConverter implementation
#pragma once

#include "pch.h"

using namespace Platform;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Interop;


namespace DataBinding
{
    public ref class DataConverter sealed : Windows::UI::Xaml::Data::IValueConverter
    {
    public:
        DataConverter();
        ~DataConverter();
        virtual Object^ Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language);
        virtual Object^ ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^ language);
    };
}

Next, we provide the implementation of DataConverter class.

Here is the full listing of DataConverter.cpp

#include "pch.h"
#include "DataConverter.h"

using namespace DataBinding;

using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Globalization::NumberFormatting;

DataConverter::DataConverter()
{
}

DataConverter::~DataConverter()
{
}

Object^ DataConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language)
{
    String^ _grade = "";
    String^ _valueString = "";
    //try parsing the value to int
    int _value = ((Windows::Foundation::IPropertyValue^)value)->GetInt32();
    if (_value < 50)
        _grade = "F";
    else if (_value < 60)
        _grade = "D";
    else if (_value < 70)
        _grade = "C";
    else if (_value < 80)
        _grade = "B";
    else if (_value < 90)
        _grade = "A";
    else if (_value < 100)
        _grade = "A+";
    else if (_value == 100)
        _grade = "SUPER STAR!";
    return _grade;
}

Object^ DataConverter::ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^ language)
{
    int _value = 0;
    String^ _grade = ((Windows::Foundation::IPropertyValue^)value)->GetString();
    if (_grade == "SUPER STAR!")
        _value = 100;
    else if (_grade == "A+")
        _value = 95;
    else if (_grade == "A")
        _value = 85;
    else if (_grade == "B")
        _value = 75;
    else if (_grade == "C")
        _value = 65;
    else if (_grade == "D")
        _value = 55;
    else if (_grade == "F")
        _value = 45;

    return _value; 
}

That’s it. Our sample is now ready.

Enjoy!!

Programming Windows Sixth Edition is coming!!!

Charles Petzold is back with “Programming Windows Sixth Edition”, updated for Windows 8. The book focuses on programming Windows 8 Apps using C# and XAML. Microsoft Press is offering an amazing deal on the upcoming book. Head over to http://blogs.msdn.com/b/microsoft_press/archive/2012/04/21/mark-your-calendars-programming-windows-sixth-edition-is-coming.aspx and learn more about the offer. Please read the terms and conditions of the offer carefully and purchase the book.

Enjoy!!!