views:

383

answers:

1

Could someone help me out, to why my listbox is empty?

The XmlDocument contains the following XML:

<Config>
  <Tabs>
    <Tab Name="Test1" />
    <Tab Name="Test2" />
  </Tabs>
</Config>

In my XAML file I have tried the following

<Window>
  <Grid>
     <ListBox DataContext="{Binding {StaticResource Data}, XPath=//Tabs}" ItemsSource="{Binding XPath=Tab/@Name}">
     </ListBox>
  </Grid>
<Window>

I know I haven't set up the binding to name attribute but shouldn't this display XmlDocument.XmlNode.ToString() for each Tab Node if it was working?

My C# Constructor Code behind:

InitializeComponent();
this.doc = new XmlDocument();
doc.LoadXml(config.document.OuterXml);
XmlDataProvider provider = (XmlDataProvider)Resources["Data"];
provider.Document = doc;
provider.Refresh();

With config.document.OuterXml being a valid document containing the above xml.

I got this working with procedural code using Collections, but I have been trying to figure out how to bind directly to XML.

Update: ListBox empty

Now there is no binding errors, but my listbox is coming up empty, I have double checked my XML file, and even did MessageBox.Show(provider.Document.OuterXML) and can confirm that the XmlDocument does have the correct nodes.

Thanks in advance

+1  A: 

If you set the XmlDataProvider's Document property to your XmlDocument, it will refresh the bindings any time the XmlNode.NodeChanged event is raised. Since Document isn't a dependency property, you can't bind to it, so you have to set it in code; this should do the trick:

In your XAML:

<Window.Resources>
   <XmlDataProvider x:Key="Data"/>
</Window.Resources>

...

<ListBox 
    DataContext="{Binding {StaticResource Data}, XPath=Config/Tabs}"
    ItemsSource="{Binding XPath=Tab/@Name}"/>

In the window's constructor:

InitializeComponent();
XmlDocument d = new XmlDocument();
d.Load("MyData.xml");
XmlDataProvider p = (XmlDataProvider)Resources["Data"];
p.Document = d;

Now any changes you make to your XmlDocument will be reflected in the ListBox.

Edit:

I can't tell you what you're doing wrong, but perhaps you'll be able to when you compare what you're doing with the below, which is a complete working example.

Window1.xaml:

<Window x:Class="Test.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1">
    <Window.Resources>
        <XmlDataProvider x:Key="Data"/>
    </Window.Resources>
    <ListBox 
        DataContext="{Binding Source={StaticResource Data}, XPath=Config}" 
        ItemsSource="{Binding XPath=Tabs/Tab/@Name}"/>     
</Window>

Window1.xaml.cs:

using System.Windows;
using System.Windows.Data;
using System.Xml;

namespace Test
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            XmlDocument d = new XmlDocument();
            string xml = @"<Config><Tabs><Tab Name='foo'/><Tab Name='bar'/></Tabs></Config>";
            d.LoadXml(xml);
            ((XmlDataProvider) Resources["Data"]).Document = d;
        }
    }
}
Robert Rossney
Thanks for that, i'll do this on monday at work and see if it works :). I'm guessing there is no way of doing this in XAML(binding the xmldataprovider to the XmlDocument?
LnDCobra
Right, because the `Document` property isn't a dependency property, and you can only bind to dependency properties.
Robert Rossney
WPF is the most unconsistent, confusing microsoft product ever! I'm now getting "Could not create an instance of type 'Binding'" when i put DataContext="{Binding {StaticResource Data}, XPath=Config/Tabs}" and google is not coming up with anything productive, tanks for noting about the dependency property above Robert :)
LnDCobra
After about 10 minutes that error dissapeared( hence why WPF is so confusing!), but now I am getting the following error: BindingExpression with XPath cannot bind to non-XML object.; XPath='Config/MarketTabs' any ideas?
LnDCobra
I am not getting any error messages now, but my ListBox is coming up empty :( any ideas?
LnDCobra
See the above update. WPF's *unforgiving*, not inconsistent. It requires a lot of care and rigor when you're trying to do something you don't fully understand, because so many of its failure modes are silent by default, and so much of its functionality is wrapped up in black boxes that you can't get to via debugging.
Robert Rossney