Archive for the ‘WPF’ Category

Namespace Mapping using XmlnsDefinition

In a typical WPF application/project we do have multiple projects/folders hence multiple namespaces.  Now when we want to use the classes from different namespaces in a XAML file, we would need to reference each namespace.

For instance, let’s say we have two projects called ABC.Presentation, ABC.WPF.  And say, we have following folders in the project hence following namespaces:

ABC.Presentation.Controls

ABC.Presentation.Behaviors

ABC.Presentation.Converters

ABC.Presentation.AttachedProperties

Now we would like to use some of the classes from these namespaces in our another project ABC.WPF.   To do that we would need to add following references inside XAML file. Of course a project reference to ABC.Presentation should be added to ABC.WPF project.


xmlns:t="clr-namespace:ABC.Presentation.Controls;assembly=ABC.Presentation"

xmlns:t="clr-namespace:ABC.Presentation.Behaviors;assembly=ABC.Presentation"

xmlns:t="clr-namespace:ABC.Presentation.Converters;assembly=ABC.Presentation"

xmlns:t="clr-namespace:ABC.Presentation.AttachedProperties;assembly=ABC.Presentation"

This makes your XAML file with bunch of references and the same thing has to be done with each XAML page in your application.   Another disadvantage with this is more maintainability.  If you change the namespace of any of existing one for any reason, now you need go to each XAML file and update there.

So it would be a better idea if we could have all of these references in a single place and Yes, it can be done.    Here are the steps:

Go to ABC.Presentation project and open AssemblyInfo.cs file.  Add XmlnsDefinition for each name space.  The first parameter is XAML namespace identifier.  This can be anything but it should be unique in your application.  Typically it is structured as Orgnization name/schema/customname.   The second parameter is CLR namespace name.  The advantage here is, we could use the same XAML namespace name for multiple CLR namespaces.


[assembly: XmlnsDefinition("http://www.abc.com/schema/presentation", "ABC.Presentation.Controls")]

[assembly: XmlnsDefinition("http://www.abc.com/schema/presentation", "ABC.Presentation.Behaviors")]

[assembly: XmlnsDefinition("http://www.abc.com/schema/presentation", "ABC.Presentation.Converters")]

[assembly: XmlnsDefinition("http://www.abc.com/schema/presentation", "ABC.Presentation.AttachedProperties")]

Now how do we make use of this identifier.   Inside the XAML file we could simply declare in a single line as shown below:


xmlns:pre="http://www.abc.com/schema/presentation"

Then using ‘pre’ we could access all the classes from different namespaces.

 
XmlnsDefinition doesn’t work: The tag/name does not exist in XML namespace

After following the steps as described above, I tried building my solution and I get the error saying the class name does not exist in namespace http: //www.ABC.com/schema/presentation.

After analyzing more I found the solution to fix the issue.  It looks like a Visual Studio bug.  After defining XAML namespace Identifier in AssemblyInfo file I built the project (ABC.Presentation) and then went to main project (ABC.Presentation where I am trying to refer the class names in XAML file), removed the project reference to ABC.Presentation.  And then re-added the reference.   That fixed the issue.


Note:
XmlnsDefinition works with foreign assemblies only.  That said, if you try to define a XAML namespace identifier for different namespaces and try to use it in the same assembly, it wouldn’t work.