Reputation: 845
I am trying to make a very simple ListBox
view that shows items from a short list as labels. However, the window pops up blank. XAML:
<Window x:Class="ReCheckList.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ReCheckList"
mc:Ignorable="d"
Title="MainWindow" Height="298" Width="192">
<Window.Resources>
<!----- Data Source ---------->
<XmlDataProvider x:Key="PackingListDataSource" XPath="cList">
<x:XData>
<Checklist xmlns="">
<ListNode Title="Socks"/>
<ListNode Title="Shoes"/>
<ListNode Title="Toothbrush"/>
</Checklist>
</x:XData>
</XmlDataProvider>
<!--- Data Template ----------->
<DataTemplate x:Key="ListNodeTemplate">
<Label Content="{Binding XPath=@Title}"></Label>
</DataTemplate>
</Window.Resources>
<Grid>
<!------ ListBox ------->
<ListBox ItemsSource="{Binding Source={StaticResource PackingListDataSource}, XPath=ListNode}"
ItemTemplate="{StaticResource ListNodeTemplate}">
</ListBox>
</Grid>
What is wrong with my data bindings?
EDIT: The most fundamental error was that the XPath
of the XmlDataProvider
did not match the root node of the xml data. Changing that to "Checklist"
was the simplest fix, not requiring modifying my XPath
search parameters.
Upvotes: 1
Views: 880
Reputation: 37059
First, remove the XPath
attribute from the XmlDataProvider
<XmlDataProvider x:Key="PackingListDataSource">
<x:XData>
<Checklist xmlns="">
<ListNode Title="Socks"/>
<ListNode Title="Shoes"/>
<ListNode Title="Toothbrush"/>
</Checklist>
</x:XData>
</XmlDataProvider>
Then, fix the XPath
in the ItemsSource
binding so it returns all ListNodes in the XML. In practice you might want to narrow it down more, but this at least gets me items in the ListBox
.
<ListBox
ItemsSource="{Binding Source={StaticResource PackingListDataSource}, XPath='//ListNode'}"
ItemTemplate="{StaticResource ListNodeTemplate}"
>
</ListBox>
//
means "Search the whole XML tree for any element with this name". Leaving that out, you're only searching the element you're looking at for anything with that name. In this case, you're looking at the root. You could explicitly start the path at root by prefacing the path with a single slash: /CheckList/ListNode
.
Alternatively (I'm learning as I go here), you could leave the binding XPath as you had it, and just change the XPath
attribute of the XmlDataProvider
to Checklist
, so your binding will look in Checklist
for ListNode
elements. Your problem was really just that cList
was wrong for that XPath
attribute because you don't have anything called cList
at the root of your XML.
<XmlDataProvider x:Key="PackingListDataSource" XPath="Checklist">
<x:XData>
<Checklist xmlns="" Title="Foo">
<ListNode Title="Socks"/>
<ListNode Title="Shoes"/>
<ListNode Title="Toothbrush"/>
</Checklist>
</x:XData>
</XmlDataProvider>
...
<ListBox
ItemsSource="{Binding Source={StaticResource PackingListDataSource}, XPath='ListNode'}"
ItemTemplate="{StaticResource ListNodeTemplate}"
>
</ListBox>
Remember that XML is case sensitive, so Checklist
is not CheckList
. And when I say you need to remember that, I really mean that I forgot it.
Upvotes: 1
Reputation: 14477
<!-- change the XPath to "Checklist" -->
<XmlDataProvider x:Key="PackingListDataSource" XPath="cList">
<x:XData>
<Checklist xmlns="">
<ListNode Title="Socks"/>
<ListNode Title="Shoes"/>
<ListNode Title="Toothbrush"/>
</Checklist>
</x:XData>
</XmlDataProvider>
Upvotes: 0
Reputation: 184524
ListNode
seems just like the wrong XPath here, did you mean //ListNode
or /Checklist/ListNode
? Also, you set an XPath
on the provider that does not appear in the data, would remove that.
Upvotes: 1