Extending the WPF XML namespaces
Rob Relyea might not like this, but today I had an idea.
When referencing controls from another assembly in XAML, one can either use xmlns:foo="clr-namespace:MyNamespace;assembly=MyAssembly"
syntax, or a URI mapped with the XmlnsDefinition
attribute. MSDN can tell you all about the attribute. Currently in Magellan I use it like this:
[assembly: XmlnsDefinition("http://xamlforge.com/magellan", "Magellan")]
[assembly: XmlnsDefinition("http://xamlforge.com/magellan", "Magellan.Abstractions")]
[assembly: XmlnsDefinition("http://xamlforge.com/magellan", "Magellan.Commands")]
[assembly: XmlnsDefinition("http://xamlforge.com/magellan", "Magellan.Behaviors")]
[assembly: XmlnsDefinition("http://xamlforge.com/magellan", "Magellan.Controls")]
[assembly: XmlnsDefinition("http://xamlforge.com/magellan", "Magellan.Framework")]
[assembly: XmlnsDefinition("http://xamlforge.com/magellan", "Magellan.Views")]
This allows you to reference any Magellan object with a simple reference:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:magellan="http://xamlforge.com/magellan"
>
The annoying thing about this, though, is you end up with ugly prefixes all over the XAML:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:magellan="http://xamlforge.com/magellan"
x:Class="Wizard.Views.Shared.Main"
>
<DockPanel>
<magellan:ZonePlaceHolder ZoneName="Left" DockPanel.Dock="Left" Width="300" />
<magellan:ZonePlaceHolder ZoneName="Right" DockPanel.Dock="Right" Width="300" />
<magellan:ZonePlaceHolder ZoneName="Content" />
</DockPanel>
</UserControl>
Today I had an idea: I can usurp the Microsoft WPF XML namespaces by adding my own controls to them. It would be as simple as changing my XmlnsDefinition
attrbutes to:
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Magellan")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Magellan.Abstractions")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Magellan.Commands")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Magellan.Behaviors")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Magellan.Controls")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Magellan.Framework")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Magellan.Views")]
Which lets me use this:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Wizard.Views.Shared.Main"
>
<DockPanel>
<ZonePlaceHolder ZoneName="Left" DockPanel.Dock="Left" Width="300" />
<ZonePlaceHolder ZoneName="Right" DockPanel.Dock="Right" Width="300" />
<ZonePlaceHolder ZoneName="Content" />
</DockPanel>
</UserControl>
Which not only reads nicer, but is also more accessible, since there's no need to manually add an import (ReSharper will add xmlns
entries for you, but unfortunately it doesn't recognise XmlnsDefinition
attributes).
My initial reaction is that this is evil, but in thinking about it, there are no Magellan classes that would conflict with classes in the WPF XML namespace. And if other libraries had the same names, you could use prefixes for those to differentiate, so that would just work. It also works fine in Blend. So the only problem that could arise is if someone else used this trick. But since it's so evil, I'd be the only one doing it, so there's no problem ;)
What do you think? Would you be disturbed by this, or would you actually find it a better experience?
Edit: It turns out that even if another library used this technique and was referenced, you can still differentiate between them by using an explicit xmlns:xyz
reference. So I am not seeing much of a downside.