开发者

WP7/ Silverlight - Unable to display XML element using Linq and WebClient

开发者 https://www.devze.com 2023-03-18 05:20 出处:网络
I am trying to display elements from an XML file hosted remotely and display in a list box. When I press the button I am getting a Formal Exception was unhandled. I have attached a screenshot of erro

I am trying to display elements from an XML file hosted remotely and display in a list box.

When I press the button I am getting a Formal Exception was unhandled. I have attached a screenshot of error![enter image description here][1]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Tasks;
using System.Xml;
using System.Xml.Linq;

namespace tvGuide
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

         }



        private void button1_Click(object sender, RoutedEventArgs e)
        {
            WebClient c = new WebClient();
            c.DownloadStringCompleted += new DownloadStringCompletedEventHandler(c_DownloadStringCompleted);
            c.DownloadStringAsync(new Uri("http://www.designized.com/tv/freeview.xml?"));
        }

        void c_DownloadStringCompleted(object sender, DownloadStringComplet开发者_StackOverflow中文版edEventArgs e)
        {
            if (e.Error != null)
                return;

            XElement r = XElement.Parse(e.Result);


            listBox1.ItemsSource = from tv in r.Descendants("programme")
                                   select new TVNZ
                                   {
                                       DisplayName = Convert.ToInt32(tv.Element("title").Value),
                                       ChannelURL = Convert.ToInt32(tv.Element("category").Value),
                                      ImageSource = Convert.ToInt32(tv.Element("url").Value),



                                   };
        }
        }

        public class TVNZ
        {
            public int DisplayName { get; set; }
            public int ChannelURL { get; set; }
            public int ImageSource { get; set; }



        }





    }

mainpage.xaml next...

<phone:PhoneApplicationPage 
    x:Class="tvGuide.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:task="clr-namespace:Microsoft.Phone.Tasks;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--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 Height="595" HorizontalAlignment="Left" Margin="6,6,0,0" Name="listBox1" VerticalAlignment="Top" Width="444">
                <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 DisplayName}" Foreground="#FFC8AB14" FontSize="28" />
                                <TextBlock Text="{Binding ChannelURL}" TextWrapping="Wrap" FontSize="24" />
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Grid>

    <!--Sample code showing usage of ApplicationBar-->
    <!--<phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>-->

</phone:PhoneApplicationPage>

And now the XML file in questions:

<tv date="20110708031152" generator-info-name="epgsnoop/0.84" generator-info-url="http://launchpad.net/epgsnoop">
- <channel id="maori-tv.freeviewnz.tv">
  <display-name>Maori TV</display-name> 
  <icon src="http://nzepg.org/logos/maori.jpg" /> 
  <url>http://www.freeviewnz.tv/</url> 
  </channel>
- <channel id="georgefm.freeviewnz.tv">
  <display-name>GeorgeFM</display-name> 
  </channel>
- <channel id="basefm.freeviewnz.tv">
  <display-name>BaseFM</display-name> 
  </channel>
- <channel id="rnz-concert.freeviewnz.tv">
  <display-name>RNZ Concert</display-name> 
  </channel>
- <channel id="stratos.freeviewnz.tv">
  <display-name>Stratos</display-name> 
  <icon src="http://nzepg.org/logos/stratos.jpg" /> 
  <url>http://www.stratostv.co.nz/</url> 
  </channel>
- <channel id="tv3.freeviewnz.tv">
  <display-name>TV 3</display-name> 
  <icon src="http://nzepg.org/logos/tv3.jpg" /> 
  <url>http://www.tv3.co.nz/</url> 
  </channel>
- <channel id="four.freeviewnz.tv">
  <display-name>Four</display-name> 
  <icon src="http://nzepg.org/logos/four.jpg" /> 
  </channel>
- <channel id="tvnz7.freeviewnz.tv">
  <display-name>TVNZ 7</display-name> 
  <icon src="http://nzepg.org/logos/tvnz7.jpg" /> 
  <url>http://www.freeviewnz.tv/</url> 
  </channel>
- <channel id="parliament.freeviewnz.tv">
  <display-name>Parliament</display-name> 
  <icon src="http://nzepg.org/logos/parliament.jpg" /> 
  <url>http://www.freeviewnz.tv/</url> 
  </channel>

Any help would be greatly appreciated.


I tried to run it but there were some issues in your code

  1. all those field must be string not int!
  2. all are optional to need to check against null
  3. attribute names were reading something different than the ones in xml!

This works:

var r = XDocument.Parse(e.Result);
listBox1.ItemsSource = from tv in r.Root.Descendants("channel")
                        let nameEl = tv.Element("display-name")
                        let urlEl = tv.Element("url")
                        let iconEl = tv.Element("icon")
                        select new TVNZ
                        {
                            DisplayName = nameEl == null ? null : nameEl.Value,
                            ChannelURL = urlEl == null ? null : urlEl.Value,
                            ImageSource = iconEl == null ? null : iconEl.Attribute("src").Value,
                        };

also change class to:

public class TVNZ
{
    public string DisplayName { get; set; }
    public string ChannelURL { get; set; }
    public string ImageSource { get; set; }
}

Conclusion: First define your problem domain before start coding.


Just one side point, using WebClient runs completely on UI thread and your application is unresponsive untill the response is back. So it's recommended to use HttpWebRequest instead which can run on a separate thread.

Here in my blog post I have prepared a helper class for async web download purposes. Feel free to use.

0

精彩评论

暂无评论...
验证码 换一张
取 消