Click here to Skip to main content
Click here to Skip to main content

A Guide to Cleaner XAML with Custom Namespaces and Prefixes (WPF/Silverlight)

, 22 Sep 2010 Ms-PL
Rate this:
Please Sign up or sign in to vote.
Clean up and manage your XAML references. This can be done using custom namespaces (scheme URLs) and custom prefixes.

Introduction

When working with any type of application, it's a good idea to split up your solution in multiple projects (assemblies) and namespaces. As your project grows, you'll see your amount of namespaces grow with it. And if you plan to use classes / controls from these namespaces in your XAML code, you'll have to declare them with the following syntax:

xmlns:PREFIX="clr-namespace:NAMESPACE" 

An example could be:

xmlns:conv="clr-namespace:Sandworks.Silverlight.NamespaceExample.Converters" 

If you are referencing an other assembly, you'll also need to add the assembly name:

xmlns:PREFIX="clr-namespace:NAMESPACE;assembly=ASSEMBLYNAME" 

For example:

xmlns:lib="clr-namespace:Sandworks.Silverlight.NamespaceExample.ClassLibrary.Converters
     ;assembly=Sandworks.Silverlight.NamespaceExample.ClassLibrary"

Some namespaces are added by default when you add a new XAML control in your project (be it a UserControl or a Page).
This is how it should look like:

<UserControl x:Class="Sandworks.Silverlight.NamespaceExample.MainPage" 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

But, as stated before, when your project starts growing and you need to work with different namespaces and assemblies, your references might start piling up and your XAML code gets bloated.

Real Life Example

In the code, you'll find the following projects:

These projects reflect how a real application could look like. All controls are organised in a separate namespace Controls (could even be another assembly) and the same thing applies to the Converters. Then you could have another assembly with more converters. Maybe this assembly contains some global converters that are used throughout all the projects in your company.

Looking at the XAML of MainPage, you'll notice the following:

<UserControl x:Class="Sandworks.Silverlight.NamespaceExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:my="clr-namespace:Sandworks.Silverlight.NamespaceExample.Controls"
    xmlns:conv="clr-namespace:Sandworks.Silverlight.NamespaceExample.Converters"
    xmlns:lib=
     "clr-namespace:Sandworks.Silverlight.NamespaceExample.ClassLibrary.Converters;
	assembly=Sandworks.Silverlight.NamespaceExample.ClassLibrary"

For this small project, I already have 3 declarations. Imagine 5 more assemblies, and 20 UserControls making use of all these assemblies. You'll end up copy/pasting, duplicating code, …

But what are our options to clean up our XAML?

Option 1: Custom Namespaces

In the example project, I added a Calendar (not a default control) to the MainPage. You'll see that Visual Studio will add a reference to System.Windows.Controls and will also add the following to your MainPage:

Notice the following:

xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
  1. Instead of adding "my" or any other word as prefix, it added sdk. It would be nice if we can trigger this behavior when adding our controls.
  2. Instead of a clr-namespace + assembly reference, it adds a regular (schema) URL.

To achieve this behavior, you need to follow the next steps:

  1. Go to the project where you want to map CLR namespaces to a custom namespace
  2. Open AssemblyInfo.cs under Properties
  3. Add the following to the top of your code
    using System.Windows.Markup;
  4. Add the XmlnsPrefix and XmlnsDefinition attributes.

Example:

[assembly: XmlnsPrefix("http://schemas.sandworks.com/sl/", "sw")]
[assembly: XmlnsDefinition("http://schemas.sandworks.com/sl/", 
	"Sandworks.Silverlight.NoNamespaceExample.Controls")]
[assembly: XmlnsDefinition("http://schemas.sandworks.com/sl/", 
	"Sandworks.Silverlight.NoNamespaceExample.Converters")]

As you can see, we use the XmlnsDefinition attribute to map multiple CLR namespaces to a single custom namespace. The beauty of this is that you aren't limited to a single assembly. In the downloadable source code, you'll see these definitions for both the application as for the class library. You could think of organising all your controls, converters, utils, … under a project wide namespace.

So, before we had this:

xmlns:my="clr-namespace:Sandworks.Silverlight.NamespaceExample.Controls"
xmlns:conv="clr-namespace:Sandworks.Silverlight.NamespaceExample.Converters"
xmlns:lib="clr-namespace:Sandworks.Silverlight.NamespaceExample.ClassLibrary.Converters;
           assembly=Sandworks.Silverlight.NamespaceExample.ClassLibrary"

And now we have this:

xmlns:sw="http://schemas.sandworks.com/sl/"

Again, imagine 5 more assemblies, and 20 UserControls making use of all these assemblies. No bloating!
If you're referencing 1 or 500 assemblies, you'll just be using this single custom namespace.

Oh, and if you didn't notice yet, the XmlnsPrefix declares the default prefix (for that namespace) that should be added automatically. When I added the Calendar, we automatically got an sdk prefix, and now for my own controls I'll automatically have the sw prefix.

Option 2: No Namespaces

Now you don't have to stop at Option 1. You could actually get rid of all your extra namespaces. As stated before, you are not limited to a single assembly. Meaning more than one assembly can declare the same namespace.

If you take a look at a default UserControl, you'll always see this line:

<UserControl x:Class="Sandworks.Silverlight.NoNamespaceExample.MainPage"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

Well, now you could map all your CLR namespace to this custom namespace, as follows:

[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", 
	"Sandworks.Silverlight.NoNamespaceExample.Controls")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", 
	"Sandworks.Silverlight.NoNamespaceExample.Converters")]

Now you achieved 2 things:

  • You do not need to add extra namespace references in your XAML controls.
  • You get rid of prefixes. Since the presentation namespace is declared without prefix, all your controls, converters, … are accessible without prefix. And this is great for using Intellisense:

I myself prefer Option 1. Totally removing namespaces and prefixes could also become a problem in larger projects. The thing I tend to do is create 1 custom namespace for company wide assemblies and 1 custom namespace for project specific assemblies/projects.

Download

The source contains 2 scenarios. One with regular namespace usage and one with our custom namespaces.
Download here: Sandworks.Silverlight.NamespaceExample.zip

More information on this topic can be found at http://msdn.microsoft.com/en-us/library/cc189061(VS.95).aspx

Enjoy!

History

  • 22nd September, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Sandrino Di Mattia
Technical Lead RealDolmen
Belgium Belgium
I'm a Technical Consultant at RealDolmen, one of the largest players on the Belgian IT market: http://www.realdolmen.com
 
All posts also appear on my blogs: http://blog.sandrinodimattia.net and http://blog.fabriccontroller.net
Follow on   Twitter

Comments and Discussions

 
QuestionMy vote for 5 Pinmembercausg6-May-13 5:09 
GeneralMy vote of 5 PinmemberSperneder Patrick3-Jan-13 20:03 
GeneralMy vote of 5 PinmemberMember 76546417-Jun-12 5:24 
clear explanation!
GeneralMy vote of 5 PinmemberChris Grove28-Sep-10 1:28 
GeneralCrashes VS2010 Pinmemberterryterryd27-Sep-10 22:47 
GeneralRe: works here Pinmembereiiv14-Oct-11 3:44 
GeneralMy vote of 5 Pinmemberp.e.rov27-Sep-10 11:47 
GeneralMy vote of 5 PinmemberFaReSs24-Sep-10 1:43 
GeneralExcellent PinmemberFaReSs24-Sep-10 1:43 
QuestionBrilliant! Can you change the VS default? Pinmemberbowlermonk22-Sep-10 6:58 
AnswerRe: Brilliant! Can you change the VS default? PinmemberSandrino Di Mattia22-Sep-10 10:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411023.1 | Last Updated 22 Sep 2010
Article Copyright 2010 by Sandrino Di Mattia
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid