views:

331

answers:

0

Hi,

I'm having trouble correctly binding a listbox to an XML datasource (text .xml file).

I'm learning how to use WPF and LINQ to XML by following the Microsoft example with the books list, which binds to an inline XML source, shown here...

http://msdn.microsoft.com/en-us/library/bb669149.aspx

What I am trying to do is change this application so that it correctly binds to an external xml file.

So, I tried to follow the modifications to the example shown in the codeproject article 238_How_to_perform_WPF_Data_Binding_using_LINQ_to_XML_-_Part_2.aspx

(XAML code is included below)

which shows how to modify the application to use an external xml file.

The problem I am having is that when the application starts the listbox does not show/load the data that is already in my xml file. The xml data string IS shown correctly in the textbox above it, and I can use the Add function to add a NEW book which is then shown correctly in the listbox, and I can select it and edit it - it just doesnt load the existing data from the xml file on startup or initialisation.

has anyone tried this example, or does anyone have a working example of either a listbox or datagrid bound to an XML file?

the XAML code I have is below, someone may be able to point out the error?

Thanks, Will

<Window x:Class="LinqToXmlDataBinding.L2XDBForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:xlinq="clr-namespace:System.Xml.Linq;assembly=System.Xml.Linq"
xmlns:local="clr-namespace:LinqToXmlDataBinding"
Title="WPF Data Binding using LINQ-to-XML" Height="665" Width="500" ResizeMode="NoResize">

<Window.Resources>
    <!-- Books provider and inline data -->
    <ObjectDataProvider x:Key="LoadedBooks" ObjectType="{x:Type xlinq:XElement}" MethodName="Load">
        <ObjectDataProvider.MethodParameters>
            <system:String>C:\Files\devel\linq example\LinqToXMLDataBinding\mydata.xml</system:String>                
            <xlinq:LoadOptions>PreserveWhitespace</xlinq:LoadOptions>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>

    <!-- Template for use in Books List listbox. -->
    <DataTemplate x:Key="BookTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Margin="3" Text="{Binding Path=Attribute[id].Value}"/>
            <TextBlock Margin="3" Text="-"/>
            <TextBlock Margin="3" Text="{Binding Path=Element[title].Value}"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

<!-- Main visual content container -->
<StackPanel Background="lightblue" DataContext="{Binding Source={StaticResource LoadedBooks}}">
    <!-- Raw XML display section -->
    <DockPanel Margin="5">
        <Label  Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" FontWeight="Bold">XML
            <Label.LayoutTransform>
                <RotateTransform Angle="90"/>
            </Label.LayoutTransform>
        </Label>
        <TextBlock Name="tbRawXml" Height="200" Background="LightGray" Text="{Binding Path=Xml}" TextTrimming="CharacterEllipsis" />
    </DockPanel>

    <Separator Height="4" Margin="5" />

    <!-- List box to display all books section -->
    <DockPanel Margin="5">
        <Label  Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" FontWeight="Bold">Book List
            <Label.LayoutTransform>
                <RotateTransform Angle="90"/>
            </Label.LayoutTransform>
        </Label>
        <ListBox Name="lbBooks" Height="200" Width="415" ItemTemplate ="{StaticResource BookTemplate}">
            <ListBox.ItemsSource>
                <Binding Path="xml"/>
            </ListBox.ItemsSource>
        </ListBox>
        <Button Margin="5" DockPanel.Dock="Right" Height="30" Width ="130" Content="Remove Selected Book" Click="OnRemoveBook">
            <Button.LayoutTransform>
                <RotateTransform Angle="90"/>
            </Button.LayoutTransform>
        </Button>
    </DockPanel>

    <Separator Height="4" Margin="5" />

    <!-- Edit current selection section -->
    <DockPanel Margin="5">
        <TextBlock Margin="5" Height="30" Width="65" DockPanel.Dock="Right" Background="LightGray" TextWrapping="Wrap" TextAlignment="Center">
                Changes are live!
            <TextBlock.LayoutTransform>
                <RotateTransform Angle="90"/>
            </TextBlock.LayoutTransform>
        </TextBlock>
        <StackPanel>
            <Label Width="450" Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" FontWeight="Bold">Edit Selected Book</Label>
            <StackPanel Margin="1" DataContext="{Binding ElementName=lbBooks, Path=SelectedItem}">
                <StackPanel Orientation="Horizontal">
                    <Label Width="40">ID:</Label>
                    <TextBox Name="editAttributeTextBox" Width="410" Text="{Binding Path=Attribute[id].Value}">
                        <TextBox.ToolTip>
                            <TextBlock FontWeight="Bold" TextAlignment="Center">
                                <Label>Edit the selected book ID and see it changed.</Label>
                            </TextBlock>
                        </TextBox.ToolTip>
                    </TextBox>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <Label Width="40">Value:</Label>
                    <TextBox Name="editValueTextBox" Width="410" Text="{Binding Path=Element[title].Value}" Height="25">
                        <TextBox.ToolTip>
                            <TextBlock FontWeight="Bold" TextAlignment="Center">
                                <Label>Edit the selected book Value and see it changed.</Label>
                            </TextBlock>
                        </TextBox.ToolTip>
                    </TextBox>
                </StackPanel>
            </StackPanel>
        </StackPanel>
    </DockPanel>

    <Separator Height="4" Margin="5" />

    <!-- Add new book section -->
    <DockPanel Margin="5">
        <Button Margin="5" Height="30" DockPanel.Dock="Right" Click ="OnAddBook">Add Book
            <Button.LayoutTransform>
                <RotateTransform Angle="90"/>
            </Button.LayoutTransform>
        </Button>
        <StackPanel>
            <Label Width="450" Background="Gray" FontSize="12" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" FontWeight="Bold">Add New Book</Label>
            <StackPanel Margin="1">
                <StackPanel Orientation="Horizontal">
                    <Label Width="40">ID:</Label>
                    <TextBox Name="tbAddID" Width="410">
                        <TextBox.ToolTip>
                            <TextBlock FontWeight="Bold" TextAlignment="Center">
                                <Label>Enter a book ID and Value pair, then click Add Book.</Label>
                            </TextBlock>
                        </TextBox.ToolTip>
                    </TextBox>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <Label Width="40">Value:</Label>
                    <TextBox Name="tbAddValue" Width="410" Height="25">
                        <TextBox.ToolTip>
                            <TextBlock FontWeight="UltraBold" TextAlignment="Center">
                                <Label>Enter a book ID and Value pair, then click Add Book.</Label>
                            </TextBlock>
                        </TextBox.ToolTip>
                    </TextBox>
                </StackPanel>
            </StackPanel>
        </StackPanel>
    </DockPanel>
</StackPanel>
</Window>