I've been trying to learn the ins-and-outs of Windows Phone 7 programming over the past few weeks. I have learned most of the basics but I've been having trouble finding a tutorial explaining exactly how to do something with XML. I want to create a very basic app which accesses an XML file at a web address and displays the various items within the file as text within the app. I've come across several tutorials which all seem to do it in a different way, or aren't explaining exactly the thing it is I want to do. I don't want to search the XML file, I don't want to update it, I just want to retrieve it's contents. Within the XML file are "items" and within those are categories like "title" and "description". I want the app to list all of the items and within each one display it's title and description.
To be more specific I know that I bind the contents to textblocks using {Binding Title} or {Binding Description}. I'm just not sure how to connect to the file using WebClient or whatever the easiest method is. I have no problem displaying the contents of an offline XML file that is already in my solution explorer.
I'm sure there is a very simple way to do this, and I really appreciate all of your help.
ScottGu created an app which demonstrates what you need. (Code below is very similar as couldn't find link to source from his example.)
The app retrieves XML from a web service (in this case from Twitter.)
private void GetTweets()
{
WebClient twtr = new WebClient();
twtr.DownloadStringCompleted += new DownloadStringCompletedEventHandler(twitter_DownloadStringCompleted);
twtr.DownloadStringAsync(new Uri("http://search.twitter.com/search.atom?&q=searchterm"));
}
It then parses the XML into a collection of object.
void twitter_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
return;
XElement xmlTweets = XElement.Parse(e.Result);
var list = new List<TweetViewModel>();
foreach (XElement t in xmlTweets.Elements("{http://www.w3.org/2005/Atom}entry"))
{
var userName = t.Element("{http://www.w3.org/2005/Atom}author").Element("{http://www.w3.org/2005/Atom}name").Value.Split(' ')[0];
var message = t.Element("{http://www.w3.org/2005/Atom}title").Value;
var imageSource = (from t2 in t.Elements("{http://www.w3.org/2005/Atom}link")
where t2.Attribute("type").Value.Contains("image")
select t2.Attribute("href").Value).First();
list.Add(new TweetViewModel
{
UserName = userName,
Message = message,
ImageSource = imageSource
});
}
twitterList.ItemsSource = list;
}
public class TweetViewModel
{
public string UserName { get; set; }
public string Message { get; set; }
public string ImageSource { get; set; }
}
This is then bound to a list.
<ListBox HorizontalAlignment="Left" Name="twitterList" VerticalAlignment="Top" Width="476">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<Image Source="{Binding ImageSource}" Height="73" Width="73" VerticalAlignment="Top" Margin="0,10,8,0"/>
<StackPanel Width="370">
<TextBlock Text="{Binding UserName}" Foreground="#FFC8AB14" FontSize="28" />
<TextBlock Text="{Binding Message}" TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
It was written with the first CTP of the tools/SDK but hopefully it should still be simple enough to get this working.
UPDATE:
I think you were right that the problem may be when I call GetRoster. This is the context in which I'm calling it:
'
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"));
}
'
What would be the correct place in which to call it? By the way I'm sorry about the code sections not appearing correctly.
Hey guys! Thanks for the help! I didn't create an account earlier so this is probably going to show up as an answer since I'm on a different computer. I did my best in changing that Twitter Tutorial into what I am trying to do. I'm getting no errors but it's not showing any content within the emulator. I created an XML file and uploaded it to my personal website. Unfortunately, I cannot get the code sample button to work even remotely well. So I'm sorry this looks so poorly. The XML file contained this info:
<?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>
Here is MainPage.xaml.cs:
private void GetRoster()
{
WebClient rstr = new WebClient();
rstr.DownloadStringCompleted += new DownloadStringCompletedEventHandler(roster_DownloadStringCompleted);
rstr.DownloadStringAsync(new Uri("http://www.MyPersonalWebsiteURL.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; }
}
}
Now MainPage.xaml:
'
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox HorizontalAlignment="Left" Name="rosterList" ItemsSource="rosterList" VerticalAlignment="Top" Width="476">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<StackPanel Width="370">
<TextBlock Text="{Binding Name}" Foreground="#FFC8AB14" FontSize="28" />
<TextBlock Text="{Binding Age}" TextWrapping="Wrap" FontSize="24" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
'
However! When I run the app in the emulator I receive no errors, but no content is displayed whatsoever. I know the solution is probably very simple so I'd like to reiterate how much your help means to me. Thanks very much for any advice you can provide.
来源:https://stackoverflow.com/questions/4138694/connect-to-xml-file-at-web-address-for-wp7-app