Silverlight WP7 App Not Displaying XML Contents
I am trying to access an online XML file and display it's contents开发者_运维问答 within a Windows Phone 7 Silverlight app. I get no errors, but when emulated no content is displayed from the XML file. From what I've gathered online, I'm simply calling things out of order. I'm just not sure what.
MainPage.xaml.cs:
namespace TwitterMix
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void GetRoster()
{
WebClient rstr = new WebClient();
rstr.DownloadStringCompleted += new DownloadStringCompletedEventHandler(roster_DownloadStringCompleted);
rstr.DownloadStringAsync(new Uri("http://www.danfess.com/data.xml"));
}
void roster_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
return;
XElement xmlPersons = XElement.Parse(e.Result);
var list = new List<RosterViewModel>();
foreach (XElement person in xmlPersons.Elements("person"))
{
var name = person.Element("name").Value;
var age = person.Element("age").Value;
list.Add(new RosterViewModel
{
Name = name,
Age = age,
});
}
rosterList.ItemsSource = list;
}
public class RosterViewModel
{
public string Name { get; set; }
public string Age { get; set; }
}
}
}
MainPage.xaml:
<Grid x:Name="ContentPanel" Grid.Row="1">
<ListBox HorizontalAlignment="Left" Name="rosterList" VerticalAlignment="Top" Width="468" Height="600">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<StackPanel Width="370">
<TextBlock Text="{Binding Name}" Foreground="White" FontSize="28" />
<TextBlock Text="{Binding Age}" TextWrapping="Wrap" FontSize="24" Foreground="White" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
And finally the contents of the XML file:
<?xml version="1.0" encoding="utf-8" ?>
<roster>
<person>
<name>Blake</name>
<age>25</age>
</person>
<person>
<name>Jane</name>
<age>29</age>
</person>
<person>
<name>Bryce</name>
<age>29</age>
</person>
<person>
<name>Colin</name>
<age>29</age>
</person>
</roster>
Any advice or suggestions are, of course, greatly appreciated. Thanks everyone for your help!
I think your problem is that the callback from DownloadStringCompleted is performed on a thread other than the UI thread. Listbox either plain ignores you or throws an exception which is swallowed by the calling thread.
You need to switch to the UI thread before assigning the itemssource property.
Dispatcher.Current.BeginInvoke((Action)(()=>rosterList.ItemsSource = list));
The same goes for assigning to any property that is databound to a UI element
If you figure out how this works in a different order I would be very interested to see it. I had to add a lot of overhead to get it going. The way I got it to work was my data class (your rosterviewmodel) inherited from INotifyPropertyChanged and all that implies. When initializing my Data Object, I set a handler up on the propertychanged event of my data object. Then in the handler what you would do is set the DataContext for your stackpanel to the object that was just changed.
Have you verified the list is being populated? Set a breakpoint before binding to rosterList and inspect list.Count.
You could just load the xml like
XDocument xmlPersons = XDocument.Load(e.Result);
var list = from query in xmlPersons.Descendants("person")
select new RosterViewModel
{
Name = (string)query.Element("name"),
Age = (int)query.Element("age")
};
rosterList.ItemsSource = list;
(code edited by hand to use your var names - not tested).
精彩评论