Search code examples
c#wpfxamllistboxxmldataprovider

Binding data from XmlDataProvider to a ListBox fails in XAML in WPF


Recently I started to learn WPF. When learning about binding data, I create a listbox and binds data from a XmlDataProvider to it. Here's the code for XmlDataProvider:

<Grid.Resources>
......
<XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
    <x:XData>
        <Expenses xmlns="">
            <Person Name="Mike" Department="Legal">
                <Expense ExpenseType="Lunch" ExpenseAmount="50" />
                <Expense ExpenseType="Transportation" ExpenseAmount="50" />
            </Person>
            <Person Name="Lisa" Department="Marketing">
                <Expense ExpenseType="Document printing"
                         ExpenseAmount="50"/>
            <Expense ExpenseType="Gift" ExpenseAmount="125" />
            </Person>
            <Person Name="John" Department="Engineering">
                <Expense ExpenseType="Magazine subscription" 
                         ExpenseAmount="50"/>
                <Expense ExpenseType="New machine" ExpenseAmount="600" />
                <Expense ExpenseType="Software" ExpenseAmount="500" />
            </Person>
            <Person Name="Mary" Department="Finance">
                <Expense ExpenseType="Dinner" ExpenseAmount="100" />
            </Person>
        </Expenses>
    </x:XData>
</XmlDataProvider>
......
</Grid.Resources>

And here's code for the Listbox:

<Grid>
......
<ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
         ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}">
<!-- Name item template -->
    <DataTemplate>
        <Label Content="{Binding XPath=@Name}"/>
    </DataTemplate>
</ListBox>
......
<Grid>

When I compile and run the code, the ListBox contains nothing. I try to find solutions from MSDN but cannot understand where the error is.


Solution

  • This should at the very least get you started. I would suggest starting off a little simpler and work your way to the more difficult solutions.

    <Window x:Class="WpfApplication1.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:WpfApplication1"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Grid.Resources>
                <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
                    <x:XData>
                        <Expenses xmlns="">
                            <Person Name="Mike" Department="Legal">
                                <Expense ExpenseType="Lunch" ExpenseAmount="50" />
                                <Expense ExpenseType="Transportation" ExpenseAmount="50" />
                            </Person>
                            <Person Name="Lisa" Department="Marketing">
                                <Expense ExpenseType="Document printing"
                             ExpenseAmount="50"/>
                                <Expense ExpenseType="Gift" ExpenseAmount="125" />
                            </Person>
                            <Person Name="John" Department="Engineering">
                                <Expense ExpenseType="Magazine subscription" 
                             ExpenseAmount="50"/>
                                <Expense ExpenseType="New machine" ExpenseAmount="600" />
                                <Expense ExpenseType="Software" ExpenseAmount="500" />
                            </Person>
                            <Person Name="Mary" Department="Finance">
                                <Expense ExpenseType="Dinner" ExpenseAmount="100" />
                            </Person>
                        </Expenses>
                    </x:XData>
                </XmlDataProvider>
            </Grid.Resources>
            <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
             DataContext="{Binding Source={StaticResource ExpenseDataSource}}" ItemsSource="{Binding Name}"/>
        </Grid>
    </Window>
    

    I trimmed your Listbox to not have the label with the datatemplate (you could actually substitute the data template for a stack panel within the Listbox. I set the data context of your listbox to be the static resource and the itemssource to be Binding Name. It will currently display the word Expenses as an individual string.