"Namespace Manager or XsltContext needed" when {Binding XPath=ns:Foo}
I'm binding DataTemplates to an XmlDataProvider. Since the XML data in question makes use of namespaces, I've also attached an XmlNamespaceManager to the XmlDataProvider and mapped a prefix to it.
When Binding to an XPath fresh off the root of the XmlDataProvider, the namespace prefix is understood just fine and I get results. However, if from within the DataTemplate I try to do another XPath based binding, the Output window shows this error at runtime:
Cannot obtain result node collection because of bad source node or bad Path.; SourceNode='IntegrationProfile'; Path='i:Role' BindingExpression:Path=; DataItem='XmlElement' (HashCode=19883454); target element is 'TabControl' (Name=''); target property is 'ItemsSource' (type 'IEnumerable') XPathException:'System.Xml.XPath.XPathException: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-define开发者_开发百科d function.
This error was provoked with this line of XAML:
<TabControl ItemsSource="{Binding XPath=i:Role}"/>
which is within a DataTemplate. The NamespaceManager was attached in code, like this:
_profile = new XmlDataProvider();
_profile.Document = new XmlDocument();
_profile.Document.Load(ProfilePath);
_profile.XmlNamespaceManager = NamespaceManager;
Is WPF forgetting that there's a NamespaceManager attached?
Found the reason and the solution myself.
Reason: The DataTemplate's DataContext is bound to the child element selected in the first query, and the scope doesn't "reach back" to where the NamespaceManager is attached.
Solution: Create an XmlNamespaceMappingCollection in the Resource block:
<Window.Resources>
<XmlNamespaceMappingCollection x:Key="MyNamespaces">
<XmlNamespaceMapping Uri="http://foo.com/MyNamespace" Prefix="i"/>
</XmlNamespaceMappingCollection>
...
</Window.Resources>
Then put the following attribute in the parent element of whatever control is making XPath queries in its bindings:
Binding.XmlNamespaceManager="{StaticResource MyNamespaces}"
Putting it in the same element next to ItemSource="..." didn't work, but making it an attribute of the parent element did.
精彩评论