Share via


Conditional Compilation in Windows Universal Apps

Introduction

Conditional compilation is the process of defining compiler directives that cause different parts of the code to be compiled, and others to be ignored. This technique can be used in a cross-platform development scenario to specify parts of the code that are compiled specific to a particular platform.[1]

Conditional compilation allows the compiler to skip some parts of the source code when compiling based on the conditional clauses. The #if ,#endif  #elif and #else directives are used for conditional compilation. These directives add conditions to parts of a source file. With the use of these directives we can keep a single source file.

#if CONDITION//some code #else//some code #endif

It tells the compiler which code is to compile for the project.

The value of the condition determines which code block is included.

conditional-symbol:
    Any identifier-or-keyword except true or false

conditional compilation directives should always be written as sets consisting of, in order, an #if directive, zero or more #elif directives, zero or one #else directive, and an #endif directive. Between these directive we have to write the conditional code.

Suppose if we have some code to be only compile if a certain condition is true we will define a condition with an ordinary if else statement. This is very helpful if we are working on a shared project.

Here is another C# example-

public int calculate(int input){   int result;       #if CONDITION   result= input + 10;       #else   result= input - 10;    #endif    return result;  }

The value of Condition will determine the functionality

CONDITION is set 

         result =  input + 10;

CONDITION is not set 

         result =  input - 10;

When to use Conditional Compilation

Using Conditional Compilation we can isolate platform-specific code so, we can use this anywhere according to our need. But if we are working on a large project it will make our code unmanageable. .Conditional compilation cannot be used in Portable Class Library because when it is compiled it generates only a single binary file .

 

Conditional Compilation in Windows Apps

In universal apps by using conditional compilation we can write code that can target different platforms i.e. Windows store and Windows Phone. We can choose which code is to compile for different project as both the project are compiled to different packages

This is the simplest way to define platform-specific code . For example, we could attempt to share our code base for  Windows Phone and Windows Store apps, and change how your code behaves for each platform by surrounding platform-specific code with a condition that can be set depending on which app or platform we are compiling for. This will be more clear with the following example

Here is an example of conditional compilation in Universal windows Apps

First we are creating a C# universal app using a blank template. The solution is created using three projects a Windows Store app, a Windows Phone app and a Shared Project.

http://www.codeproject.com/KB/cs/845485/1.png

The first thing we notice in the solution is that both the windows store and windows phone projects have a separate start page which is the Main page. But we have to share this page so we will just drag one of them to the shared project and then we will delete the Main page from the other two projects. It wont create any problem as it is just a blank page.

Now we have a common shared Main page.

Before:

http://www.codeproject.com/KB/cs/845485/4.png

 

After:

http://www.codeproject.com/KB/cs/845485/5.png

In the Main page of shared project we are creating a simple UI, just a Button with an event handler and a TextBlock  in which we want to display   “Windows Store” if it is a Windows store app or “Windows Phone” if it is a Windows Phone app on a button click.

We will do this with conditional compilation in button click event handler

We will add conditions

#if WINDOWS_APP#elif WINDOWS_PHONE_APP

We can see this condition by going to  Properties->Build->Condition compilation symbols

Here in Windows properties the Conditional compilation symbol defined are NETFX_CORE and WINDOWS_APP and in Windows phone properties, NETFX_CORE and WINDOWS_PHONE_APP .

Windows 8  have a compiler directive set called NETFX_CORE. So, this is always set for a Windows 8 project and common in both Windows store and Windows phone.

Even we can add our compilation condition here, say "MY_COMPILATION_CONDITION"  and can use this in our project but let’s go with the default one.

 

http://www.codeproject.com/KB/cs/845485/properties1.png

 

Our condition here is, if it is a windows phone application we want to display “Windows Phone” else we want to display “Windows store”. So in the event handler we will use Condition Compilation

http://www.codeproject.com/KB/cs/845485/codec_.png

 

We can see some code here is grayed out, this is just because intellisense is helping us with our conditional compilation. We can swap from windows to windows phone from the dropdown menu at the top. We can see here our platform is set to Windows , so the code related to other platform is grayed out. This is a very helpful feature as we can easily notice which code is going to compile specific to platforms.

 

http://www.codeproject.com/KB/cs/845485/switch.png

 

Right click on the Windows project and select "Set as startup project" Now if we run the windows app by clicking on the button we get

http://www.codeproject.com/KB/cs/845485/win1.png

 And if we select Windows phone as start-up project and run the project , Windows phone project will be running and we can see it is displaying Windows Phone instead of Windows Store.

http://www.codeproject.com/KB/cs/845485/phone1.png

 

An alternative way to share the view is

Conditional Compilation in XAML

If we use a TopAppBar in our shared project the application will run perfectly in windows store but we will get an exception in windows phone as top app bar is not available for windows phone.

There is a good way to manage differences between of XAML between Windows and Windows Phone is by using XAML Conditional Compilation. XCC is a preprocessor adding conditional compilation support to XAML files. We can enable XCC in your project by installing a tiny NuGet package.It supports Windows Universal apps and Xamarin Forms projects.

We will add this through nuget package manager. We will do this on solution level as we have to add this to both the projects. Whenever we reference any library or package from the shared project it needs to be added to both the projects.

Open the solution context menu and select "Manage NuGet Package for Solution". Search for xcc and install the XAML Conditional Compilation NuGet package in both projects.

http://www.codeproject.com/KB/cs/845485/xcc.png

 

After we have added the nuget package we have to declare it in the Main page where we want to use it.

We are adding the conditions for windows app and windows phone app

xmlns:win="condition:WINDOWS_APP" xmlns:wp="condition:WINDOWS_PHONE_APP"

The xmlns:win and xmlns:wp attributes define the namespaces for conditional compiled XML elements and attributes.  xmlns:win is used when we want the code to be compile for only windows store app and xmlns:wp is used when we want the code to be compiled for only Windows Phone app.

We have also to add it to be ignored else VS will give errors

mc:Ignorable="d win wp"

The mc:Ignorable attribute ensure the new xmlns prefixes are ignored by designers and compilers.

With the conditional compilation namespaces in place we can now enter the following XAML.Now we have to just add a prefix “win” or “wp” to our controls. Here in our example we want our TopAppBar to show only when it is a Windows Store application so we will add “win” to “Page.TopAppBar”.

I have also added “wp” to “Page.BottomAppBar”. Now it will only compile to windows Phone application.

 

http://www.codeproject.com/KB/cs/845485/xcccode.png

 

If we run Windows App it will show only the Top App Bar

http://www.codeproject.com/KB/cs/845485/win2.png

 

If we run Windows Phone App it will show only the Command Bar.

http://www.codeproject.com/KB/cs/845485/winphone2.png

 

Intellisense does not work when we apply a custom prefix to an XML element. But we  can enable Intellisense support by adding the  mc:ProcessContent attribute.

Tips and Best practices

Don’t use  #else if, #elseif or #elsif they won't work. You can use #elif instead.

XCC is in beta version so use it carefully.

If we use XCC to particular control, we won’t be able to see it at design time. My trick is to design it first and when I am satisfied with it I apply the Conditional Compilation to it.

Source Code

Download the source code used in the examples from here, Conditional Compilation and Conditional Compilation of XAML

References

https://msdn.microsoft.com/en-us/library/windows/apps/jj714084%28v=vs.105%29.aspx?f=255&MSPPError=-2147217396

https://github.com/firstfloorsoftware/xcc/wiki

https://xcc.codeplex.com/wikipage?title=Xamarin%20Forms