Welcome to EMC Consulting Blogs Sign in | Join | Help

Johan van Staden's Blog

Wam .BAML thank you .XAML

I was reading through Andrew Troelsen’s latest book, Pro C# 2010 and the .NET 4 Platform and came across this little beauty. I’ve heard about creating pure xaml appliations but I’ve never actually seen it. Probably a good time to point out that it is NOT a good idea to take this “single file” approach in real life for many many reasons and this is one of those “because I can” moments. Nonetheless, I was still curious and learned a few interesting things along the way.

I used a very cool editor called kaxaml logo . For out of Visual Studio coding I would encourage you to have a look at it…and it is free!

Our application will exist of 2 .xaml files and one script file for MSBuild. Currently your C# compiler does not understand xaml markup that well, hence us using MSBuild to transform our code into a valid .NET assembly.

This blog is not about creating a flashy WPF app, but rather proving the xaml only point, so excuse the boring Hello World app. Regarding the two xaml files, one will represent the application itself and the other the actual window that will contain the button. Later on you’ll see the script file defining them as the “Application Definition” and the “Page” respectively.

We will start with the Window. I named it HellowWorld.xaml. Look at the code below.

<!-- Defining the window -->
<Window x:Class="PureXAML.HelloWorld"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Pure xaml baby, YEAH!"
  Height="200" Width="300" WindowStartupLocation="CenterScreen">

  <!-- Defining the Button -->
  <Button x:Name="btnHelloWorld" Width="133" Height="24"
          Content="Hello World" Click="btnHelloWorld_Clicked"/>
  
  <!-- The implementation of the onclick event -->
  <x:Code>
   <![CDATA[
   private void btnHelloWorld_Clicked(object sender, RoutedEventArgs e)
   {
      this.Close();
   }
   ]]>
  </x:Code>
</Window>

Firstly you will see the <Window> that specifies the class name and define those old familiar namespaces. The rest of the attributes are all self-explanatory.  Then you’ll see on line 9 that we create a button and do note the click event.  Finally, line 13, we get to the <x:Code> element which allows you to create event handlers and other methods and as you can see there is normal code inside!

If we now move to our Application xaml file, which is called HelloApp.xaml you’ll see how we reference our xaml file we created here at the top.

<Application  x:Class="PureXAML.HelloApp"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  StartupUri="HelloWorld.xaml" Exit="AppExit">
  <x:Code>
   <![CDATA[
   private void AppExit(object sender, ExitEventArgs e)
   {
      MessageBox.Show("Goodbye world");
   }
   ]]>
  </x:Code>  

</Application>

Nothing too surprising here, but note StartupUri and Exit on line 4. StartupUri specifies which xaml resource should be loaded and a Main() would be generated during compile time. Exit on the other hand, unlike Main(), is not generated automatically and proves that you can use <x:Code> to catch these other code blocks you may want to use. Note how we handle the AppExit event.

The last piece of the puzzle is the script file and even though it has an extension of .csproj you won’t be able to open it with Visual Studio as it won’t understand due our minimal code in it. This is a very skinny script that is just enough for MSBuild to understand. I’ve named it PureXAML.csproj. Have a look at the <ItemGroup> elements and note how we reference some external assemblies and also how we specify the ApplicationDefinition and Page.

<Project DefaultTargets="Build"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <RootNamespace>PureXAML</RootNamespace>
    <AssemblyName>PureXAML</AssemblyName>
    <OutputType>winexe</OutputType>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
  </ItemGroup>
  <ItemGroup>
    <ApplicationDefinition Include="HelloApp.xaml" />
    <Page Include="HelloWorld.xaml" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
</Project>

In his book Andrew calls the “.targets”, lines 18 and 19, the magical bit. The Microsoft.WinFX.targets enables us to convert xaml into C# code files while the Microsoft.CSharp.targets contains data to interact with the C# Compiler itself.  So if you look at our file structure now in Windows Explorer it looks like this.

BeforeMSBuild

I now open my VS Command Prompt, and once I’m in the relevant directory I run the following command. Msbuild PureXAML.csproj

msbuild

Suddenly if you look at our file structure you’ll see the old familiar bin and obj directory.

AfterMSBuild_1

In the bin directory you’ll find the expected .exe and if you run that you will see our master piece come to life.

AfterMSBuild_bin_folder

Dialog1Dialog2 

 

I hear you ask…”Why baml in the blog title then?” Well let me answer you. If you drill into you obj directory that MSBuild created for you, you’ll discover a few oddities. Have a look.

AfterMSBuild_obj_folder

You’ll see our .xaml files have been turned into .cs files, where the.g prefix stands for autogenerated. Those previously mentioned .targets files are directly responsible for this. Which brings us to our .baml file. MSBuild took our window file, HellowWorld.xaml, and created a Binary Application Markup Language file. This is a binary representation of the original .xaml file and will now be embedded as a resource in the assembly. You can take reflector and see that it is used as a resource. The baml file contains all the necessary interface attributes to make this page look like you see it, like the Height and Width we specified earlier for example.  So in short, the .baml file is a resource file that will be referenced at runtime.

Hope you found it mildly interesting at least…if you did get the book I mentioned, there are still loads about it.

Thanks for reading, hope you enjoyed.

Published Tuesday, September 21, 2010 11:31 PM by johan.vanstaden

Comments

No Comments
Anonymous comments are disabled
Powered by Community Server (Personal Edition), by Telligent Systems