Compilation directives for controlling XAML content

In C# in order to control what code should be executed we can use compilation directives #if, #else, #elif and #endif. For instance, we can compile certain code only in Debug mode and exclude one in Release. #if directive can be used not only to test for symbols DEBUG and RELEASE. We are able to define any symbols. Let’s take a look how to do that and how to use newly defined symbol in the code. For example, we want to add some funny log messages when symbol FUN_MODE is defined.

  1. First, define a new compilation symbol for the whole project in the project’s properties:Compilation directive XAML 1 FUN_MODE
  2. Then we can check for defined symbol in the code:
    #if FUN_MODE
        logger.Debug("Yahoo! It looks like our app finally works!");
    #else
        logger.Debug("Application started.");
    #endif

Everything is quite simple. The question is how to achieve the same in XAML code.

We’ve already defined custom compilation symbol and want to show different content on the view depends on the symbol FUN_MODE presence. Hopefully, Open XML provides an AlternateContent element that works similarly to switch in C#. It provides a possibility to check defined XML namespaces and make a choice between different content. However, we need to do a little trick to map our compilation symbol to XML namespace.

  1. Use XmlnsDefinitionAttribute in the project’s AssemblyInfo.cs to create a new XML namespace definition, and surround it with the compilation directives #if … #endif.
    #if FUN_MODE
    [assemblyXmlnsDefinition("Fun_Mode""MySolution.ProjectNamespace")]
    #endif

    Project’s assembly has the Fun_Mode definition only when FUN_MODE symbol is defined. The right namespace of the project should be used as the second parameter.

  2. Define Fun_Mode in the view and use AlternateContent to provide different XAML:
    <UserControl x:Class="MySolution.ProjectNamespace.LoginView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:fun="Fun_Mode"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
      <Grid>
        <mc:AlternateContent>
          <mc:Choice Requires="fun">
            <TextBlock Text="Hi! As usual enter admin:111 and have a nice day! :)" />
          </mc:Choice>
          <mc:Fallback>
            <TextBlock Text="Welcome! Please, enter your login and passsword." />
          </mc:Fallback>
        </mc:AlternateContent>
      </Grid>
    </UserControl>

AlternateContent contains one or many Choice elements (but at least one is required). Choice.Requires points to the XML namespace definition (xmlns:fun in the example). If it is defined then XAML code inside the Choice element is used. A code inside the Fallback element is used when there are no used Choice elements.

Now in order to disable fun mode we need just to remove compilation symbol FUN_MODE from the project’s properties. That will disable definition of assembly attribute. And, as a result, xmlns:fun will point to nothing. The code in the Choice element will be ignored and the code in Fallback element will be used.

In case we need to show the text only when FUN_MODE isn’t defined we just need to leave the Choice element empty.

4 thoughts on “Compilation directives for controlling XAML content

  1. Hi! Thanks for this post it’s just what i was looking for and it’s clearer that the answer on SO http://stackoverflow.com/a/19940157/665823 .

    Am using VS2010 and it seems it’s not working as expected. When adding/removing compilation symbol FUN_MODE the xaml builder changes accordingly.

    In the other hand the generated baml file always contains the Fallback content and so does the runing program. Am struggling with this, and i don’t know if am missing something (nuget package, plugin, extra configuration).

    If you can help me i’ll really appreciate it. Thx.

    1. It would be very helpful if you create some simplified application like “Hello World” to reproduce the issue, and upload it somewhere (e.g. GitHub).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s