XamlReader - mapping multiple CLR namespaces to single XML namespace
-
07-03-2021 - |
Pergunta
I have a WPF project with an AssemblyInfo.cs
that groups multiple CLR namespaces into a single XML namespace:
[assembly: XmlnsDefinition("http://foo.bar", "MyLibary.Controls")]
[assembly: XmlnsDefinition("http://foo.bar", "MyLibary.Converters")]
In XAML this is used like so:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:fb="http://foo.bar">
<fb:FooButton IsEnabled="{Binding Something, Converter={fb:FooConverter}}"/>
</UserControl>
This works great when the XAML is instantiated normally, but now I am now trying to dynamically load XAML files from my project using XamlReader
.
The problem: I can't seem to map multiple CLR namespaces to a single XML namespace. It seems that the last definition added to the XamlTypeMapper
is the only one that persists (e.g. it clobbers previous registrations):
var parserContext = new ParserContext();
parserContext.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
parserContext.XmlnsDictionary.Add("fb", "http://foo.bar");
parserContext.XamlTypeMapper = new XamlTypeMapper(new string[] {"MyLibrary"});
parserContext.XamlTypeMapper.AddMappingProcessingInstruction("http://foo.bar", "MyLibrary.Converters", "MyLibrary");
parserContext.XamlTypeMapper.AddMappingProcessingInstruction("http://foo.bar", "MyLibrary.Controls", "MyLibrary");
...
var rootNode = XamlReader.Load(memeoryStream, parserContext) as FrameworkElement
The error message is:
'Cannot create unknown type '{http://foo.bar}MyConverter'.'
If all put all my code under a single common CLR namespace, everything works but unfortunately this is not option. Has anybody mapped multiple CLR namespaces to a single XML namespace for the purpose of loading XAML content dynamically?
Thanks in advance!
Solução
As mentioned in the comments above, the solution is to manually load the assembly before invoking XamlReader.Load
and removing the type mapper and context all together:
Assembly.Load("MyLibrary");
var rootNode = XamlReader.Load(memeoryStream) as FrameworkElement
I would have assumed since the XamlTypeMapper
is initialized with a list of assemblies, that this class would be responsible for loading the assembly (and maybe it is) but the behaviour of AddMappingProccessingInstruction
prevents this from working.