Generation App – Dia 14 – Descarga de datos usando un WebClient

En este día es momento que aprendas como descargar y obtener datos de un cliente web (o WebClient) creando un lector básico de RSS. La guía y ejemplos de códigos en este tópico son basado de un ejemplo llamado “RSS Reader Sample”, el cual puede ser descargado de los proyectos ejemplo para Windows Phone. En el siguiente video te mostrare paso a paso como cumplir esta tarea.

  1. Ejecuta Visual Studio 2010 Express para Windows Phone.

  2. Crea un nuevo proyecto seleccionando haciendo clic en Archivo | Nuevo Proyecto

  3. La ventana de Nuevo Proyecto aparece. Expande las plantillas de Visual C#, y selecciona la plantilla Silverlight para Windows Phone.

  4. Ahora selecciona la plantilla Aplicación Windows Phone. Coloca de nombre de proyecto tu preferencia.

  5. Da clic a OK. La ventana de selección de plataforma Windows Phone aparece. Selecciona Windows Phone OS 7.1 para la versión de Windows Phone objetivo.

  6. Da clic a OK. El proyecto nuevo es creado y se despliega el archivo MainPage.xamlen el diseñador de Visual Studio.Ahora debemos agregar una Referencia. Da un clic derecho sobre el proyecto, y da clic en Add Reference, y selecciona la pestanaBrowse.

    Navega hacia el directorio de Archivos de Programas (o ProgramFiles), y dirígete hacia el directorio Microsoft SDKs/Silverlight/v4.0/Libraries/Client/ y seleccionaSystem.ServiceModel.Syndication.dll y da clic a Ok.

  7. Ahora agregaremos una nueva clase. Da clic derecho sobre el proyecto, seleccionaAdd -> Class.

  8. Lo nombraremos como RssTextTrimmer y le damos clic a Add

  9. Da doble clic sobre el archivo RssTextTrimmer.cs en el Solution Explorer

  10. Agrega la siguientes directivas

    using System.Windows.Data;
    using System.Globalization;
    using System.Text.RegularExpressions;
  11. Actualiza la definición de la clase, a modo que implemente la interfaz IValueConverter

    public class RssTextTrimmer : IValueConverter
  12. Agrega el siguiente código a la clase RssTextTrimmer:

    // Clean up text fields from each SyndicationItem. 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return null;
    
        int maxLength = 200;
        int strLength = 0;
        string fixedString = "";
    
        // Remove HTML tags and newline characters from the text, and decode HTML encoded characters. 
        // This is a basic method. Additional code would be needed to more thoroughly  
        // remove certain elements, such as embedded Javascript. 
    
        // Remove HTML tags. 
        fixedString = Regex.Replace(value.ToString(), "<[^>]+>", string.Empty);
    
        // Remove newline characters.
        fixedString = fixedString.Replace("\r", "").Replace("\n", "");
    
        // Remove encoded HTML characters.
        fixedString = HttpUtility.HtmlDecode(fixedString);
    
        strLength = fixedString.ToString().Length;
    
        // Some feed management tools include an image tag in the Description field of an RSS feed, 
        // so even if the Description field (and thus, the Summary property) is not populated, it could still contain HTML. 
        // Due to this, after we strip tags from the string, we should return null if there is nothing left in the resulting string. 
        if (strLength == 0)
        {
            return null;
        }
    
        // Truncate the text if it is too long. 
        else if (strLength >= maxLength)
        {
            fixedString = fixedString.Substring(0, maxLength);
    
            // Unless we take the next step, the string truncation could occur in the middle of a word.
            // Using LastIndexOf we can find the last space character in the string and truncate there. 
            fixedString = fixedString.Substring(0, fixedString.LastIndexOf(" "));
        }
    
        fixedString += "...";
        return fixedString;
    }
    
    // This code sample does not use TwoWay binding, so we do not need to flesh out ConvertBack.  
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
  13. Establece la clase RssTextTrimmer como un converter dándole doble clic aApp.xaml en el Solution Explorer, y agregando el siguiente código dentro de la etiqueta <Application.Resources>

    <converter:RssTextTrimmer xmlns:converter="clr-namespace:sdkRSSReaderCS" x:Key="RssTextTrimmer" />
    Donde sdkRssReaderCS es el nombre del namespace de tu proyecto.

Actualizar el código XAML

  1. Da un doble-clic sobre MainPage.xaml en el Solution Explorer

  2. Reemplaza  <Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″></Grid> con el siguiente código XAML:

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,12,0">
        <Button Content="Load Feed" Height="72" HorizontalAlignment="Left" Margin="9,6,0,0" Name="loadFeedButton" VerticalAlignment="Top" Width="273" Click="loadFeedButton_Click" />
    
        <ListBox Name="feedListBox" Height="468" HorizontalAlignment="Left" Margin="20,100,0,0" VerticalAlignment="Top" Width="444" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionChanged="feedListBox_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel VerticalAlignment="Top">
                        <TextBlock TextDecorations="Underline" FontSize="24" Name="feedTitle" TextWrapping="Wrap" Margin="12,0,0,0" HorizontalAlignment="Left" Foreground="{StaticResource PhoneAccentBrush}" Text="{Binding Title.Text, Converter={StaticResource RssTextTrimmer}}" />
                        <TextBlock Name="feedSummary" TextWrapping="Wrap" Margin="12,0,0,0" Text="{Binding Summary.Text, Converter={StaticResource RssTextTrimmer}}" />
                        <TextBlock Name="feedPubDate" Foreground="{StaticResource PhoneSubtleBrush}" Margin="12,0,0,10" Text="{Binding PublishDate.DateTime}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Border BorderBrush="{StaticResource PhoneSubtleBrush}" BorderThickness="1" Height="2" HorizontalAlignment="Left" Margin="20,88,0,0" Name="border1" VerticalAlignment="Top" Width="438" />
    </Grid>

Actualizando el codigo C#

  1. Agrega las siguientes directivas

    using System.IO;
    using System.ServiceModel.Syndication;
    using System.Xml;
    using Microsoft.Phone.Tasks;
  2. Agrega el siguiente código en la clase MainPage, después del constructor:

    // Click handler that runs when the 'Load Feed' or 'Refresh Feed' button is clicked. 
    private void loadFeedButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        // WebClient is used instead of HttpWebRequest in this code sample because 
        // the implementation is simpler and easier to use, and we do not need to use 
        // advanced functionality that HttpWebRequest provides, such as the ability to send headers.
        WebClient webClient = new WebClient();
    
        // Subscribe to the DownloadStringCompleted event prior to downloading the RSS feed.
        webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
    
        // Download the RSS feed. DownloadStringAsync was used instead of OpenStreamAsync because we do not need 
        // to leave a stream open, and we will not need to worry about closing the channel. 
        webClient.DownloadStringAsync(new System.Uri("http://windowsteamblog.com/windows_phone/b/windowsphone/rss.aspx"));
    }
    
    // Event handler which runs after the feed is fully downloaded.
    private void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                // Showing the exact error message is useful for debugging. In a finalized application, 
                // output a friendly and applicable string to the user instead. 
                MessageBox.Show(e.Error.Message);
            });
        }
        else
        {
            // Save the feed into the State property in case the application is tombstoned. 
            this.State["feed"] = e.Result;
    
            UpdateFeedList(e.Result);
        }
    }
    
    // This method determines whether the user has navigated to the application after the application was tombstoned.
    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        // First, check whether the feed is already saved in the page state.
        if (this.State.ContainsKey("feed"))
        {
            // Get the feed again only if the application was tombstoned, which means the ListBox will be empty.
            // This is because the OnNavigatedTo method is also called when navigating between pages in your application.
            // You would want to rebind only if your application was tombstoned and page state has been lost. 
            if (feedListBox.Items.Count == 0)
            {
                UpdateFeedList(State["feed"] as string);
            }
        }
    }
    
    // This method sets up the feed and binds it to our ListBox. 
    private void UpdateFeedList(string feedXML)
    {
        // Load the feed into a SyndicationFeed instance.
        StringReader stringReader = new StringReader(feedXML);
        XmlReader xmlReader = XmlReader.Create(stringReader);
        SyndicationFeed feed = SyndicationFeed.Load(xmlReader);
    
        // In Windows Phone OS 7.1, WebClient events are raised on the same type of thread they were called upon. 
        // For example, if WebClient was run on a background thread, the event would be raised on the background thread. 
        // While WebClient can raise an event on the UI thread if called from the UI thread, a best practice is to always 
        // use the Dispatcher to update the UI. This keeps the UI thread free from heavy processing.
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            // Bind the list of SyndicationItems to our ListBox.
            feedListBox.ItemsSource = feed.Items;
    
            loadFeedButton.Content = "Refresh Feed";
        });
    }
    
    // The SelectionChanged handler for the feed items 
    private void feedListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListBox listBox = sender as ListBox;
    
        if (listBox != null && listBox.SelectedItem != null)
        {
            // Get the SyndicationItem that was tapped.
            SyndicationItem sItem = (SyndicationItem)listBox.SelectedItem;
    
            // Set up the page navigation only if a link actually exists in the feed item.
            if (sItem.Links.Count > 0)
            {
                // Get the associated URI of the feed item.
                Uri uri = sItem.Links.FirstOrDefault().Uri;
    
                // Create a new WebBrowserTask Launcher to navigate to the feed item. 
                // An alternative solution would be to use a WebBrowser control, but WebBrowserTask is simpler to use. 
                WebBrowserTask webBrowserTask = new WebBrowserTask();
                webBrowserTask.Uri = uri;
                webBrowserTask.Show();
            }
        }
    }

Asegúrate que debes tener internet para capturar los datos solicitados.

Autor: Jorge Ramirez      Síguelo en twitter @JorgeRamirezMSP
Publicación original –> http://j.mp/UTKvr9
Fuente 1 –> http://j.mp/13e2kFi

Anuncios

1 comentario

Archivado bajo Windows Phone

Una respuesta a “Generation App – Dia 14 – Descarga de datos usando un WebClient

  1. Pingback: Con Generation App nunca fue tan fácil desarrollar para Windows Phone « El Blog de MSP para Latinoamerica [BETA]

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s