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!

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top