Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1909, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Creare un aggregatore di feed RSS con VB 2008, WPF & LINQ - quinta parte

In questo quinto post della serie dedicata alla ricostruzione dell’applicazione Custom WPF RSS Feed Aggregator che ho pubblicato su CodePlex, renderemo definitivamente operativa l’applicazione stessa, facendo utilizzo di ulteriori tecniche relative a Windows Presentation Foundation e LINQ-to-Xml tramite Visual Basic 2008.

 

La scorsa volta avevamo scritto un metodo per popolare la TreeView con l’elenco dei siti Web/blog suddivisi per categorie. Ora dobbiamo gestire la selezione di ciascun sito nella TreeView e far sì che, per ciascun sito, vengano caricati i relativi feed RSS le cui informazioni debbono poi essere mostrate nella ListView. L’evento da gestire per la TreeView si chiama MouseLeftButtonUp e il relativo codice, di cui seguiranno i commenti, è il seguente:

 

    Private Sub SiteTreeView_MouseLeftButtonUp(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles SiteTreeView.MouseLeftButtonUp

 

        Try

            'First, obtains the instance of the TreeView

            Dim tempTreeview As TreeView = DirectCast(sender, TreeView)

            'Second, obtains the instance of the selected TreeViewItem

            Dim tempTreeViewItem As TreeViewItem = DirectCast(tempTreeview.SelectedItem, TreeViewItem)

 

            'Data-binding calling a method which receives the tag (which contains the URL) for the selected Author

            Me.DataContext = HelperMethods.RetrieveFeeds(tempTreeViewItem.Tag.ToString)

 

            PostCollection = CType(CollectionViewSource.GetDefaultView(Me.DataContext), CollectionView)

 

            ViewingLabel.Content = tempTreeViewItem.Header.ToString

        Catch ex As WebException

            MessageBox.Show("Could not access the web site. Probably no Internet connection available", "", MessageBoxButton.OK, MessageBoxImage.Error)

 

        Catch ex As FileNotFoundException

            MessageBox.Show("Could not access the web site. Probably invalid feed Url", "", MessageBoxButton.OK, MessageBoxImage.Error)

 

        Catch ex As Exception

 

        End Try

    End Sub

 

Mediante conversione esplicita del Sender, otteniamo l’istanza della TreeView. Questa espone una proprietà SelectedItem che è di tipo TreeViewItem, quindi un singolo elemento della TreeView. Per ottenerne l’istanza è necessaria un’ulteriore conversione in TreeViewItem.

Mediante l’assegnazione della proprietà DataContext dell’oggetto Window1 (Me) stabiliamo la sorgente dati che costituirà l’origine per il data-binding. Tale sorgente dati è costituita dai feed RSS recuperati mediante il metodo RetrieveFeeds che avevamo implementato in precedenza e che riceve, come argomento, l’Url del sito da elaborare, contenuto nella proprietà Tag dell’oggetto TreeViewItem selezionato. L’assegnazione di DataContext farà sì che la ListView sottostante faccia riferimento proprio a questa per popolare, come conseguenza, la propria proprietà ItemsSource, quindi l’elenco degli elementi.

 

L’assegnazione dell’oggetto PostCollection ci consente di ottenere un’infrastruttura per sfogliare, ordinare, filtrare l’origine dati, la cui forma corretta è data dal metodo GetDefaultView. Circa la gestione delle eccezioni, sostanzialmente si spiegano da sole mentre la decisione di non intraprendere alcuna azione nel caso di un’eccezione generica dipende dal fatto che, quando l’utente clicca su una delle categorie e non su un sito, non bisogna fare nulla.

 

Il seguente gestore di evento assicura che, quando ciascun elemento della ListView riceve il focus, ci sia allineamento tra lo stesso e l’oggetto corrispondente nella PostCollection:

 

    Private Sub Item_GotFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

 

        Dim item = CType(sender, ListViewItem)

        Me.FeedListView.SelectedItem = item.DataContext

 

    End Sub

 

L’ultima implementazione che dobbiamo eseguire riguarda la funzionalità che permetta di aggiungere nuovi siti/blog al documento XML di base attraverso l’interfaccia. Questa operazione può essere attivata nel gestore di evento Click del pulsante AddFeedButton il quale si accerterà, tra l’altro, che l’utente abbia specificato sia il nome dell’autore del sito/blog che l’Url, informazioni entrambe necessarie. La categoria di appartenenza del nuovo indirizzo sarà invece determinata dal contenuto della ComboBox:

 

    Private Sub AddFeedButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

 

        Try

            'If both Author and Feed URL are specified

            If String.IsNullOrEmpty(NewFeedAuthorTextBox.Text) = False AndAlso String.IsNullOrEmpty(NewFeedUrlTextBox.Text) = False Then

 

                'Let's set a TreeViewItem for the new feed URL

                Dim newFeed As New TreeViewItem

                With newFeed

                    .Header = NewFeedAuthorTextBox.Text  'Author Name

                    .Tag = NewFeedUrlTextBox.Text  'Feed URL

                    .FontWeight = FontWeights.Normal

                End With

 

                'Iterates the treeview to find the node where the new feed belongs to

                For Each MainSite As TreeViewItem In SiteTreeView.Items

                    If MainSite.Header.ToString = MainSitesComboBox.Text Then

                        MainSite.Items.Add(newFeed)

                        Exit For

                    End If

                Next

 

                'Let's write back the Xml file with updates

                HelperMethods.WriteXml(Me.SiteTreeView, AppDomain.CurrentDomain.BaseDirectory + "Websites.xml")

            End If

 

        Catch ex As Exception

 

            MessageBox.Show(ex.ToString)

        End Try

 

    End Sub

 

Come potete osservare, in modo molto semplice viene istanziato un nuovo TreeViewItem che rappresenti il nuovo sito/blog. La successiva iterazione For..Each va a determinare la categoria di appartenenza del nuovo sito e aggiunge il relativo TreeViewItem al nodo della TreeView appropriato.

Al termine di questo semplice lavoro, viene chiamato un metodo WriteXml che riceve, come argomenti, la TreeView da cui leggere i dati e il nome del file in cui salvarli. Tale metodo deve essere predisposto nella classe HelperMethods come segue:

 

    Shared Sub WriteXml(ByVal SiteTreeView As TreeView, ByVal FileName As String)

 

        'Querying the treeview to dinamically generate XML nodes

        Dim xmlDoc As XDocument = <?xml version="1.0" encoding="utf-8"?>

                                  <WebSites>

                                      <%= From item In SiteTreeView.Items _

                                          Let realItem = DirectCast(item, TreeViewItem) _

                                          Select <MainSite Name=<%= realItem.Header %>>

                                                     <%= From WebSite In realItem.Items _

                                                         Let subWebSite = DirectCast(WebSite, TreeViewItem) _

                                                         Select <Site Author=<%= subWebSite.Header %> URL=<%= subWebSite.Tag %>/> %>

                                                 </MainSite> %>

                                  </WebSites>

 

        xmlDoc.Save(FileName)

    End Sub

 

La prima considerazione che voglio fare a questo punto è: con una decina di righe di codice, e grazie all’utilizzo degli XML Literals e delle espressioni incorporate di Visual Basic 2008, è possibile scrivere un documento XML di qualsivoglia lunghezza e struttura, certi che il codice rimane invariato. Un buon tutorial sull’uso delle espressioni incorporate e degli XML Literals, oltre che le trattazioni nel mio libro su LINQ, è costituito da questo mio articolo su LINQ-to-Xml, che vi consiglio di leggere se non avete dimestichezza con questi concetti.

 

Come si può vedere, la prima query incorporata ottiene l’elenco delle categorie, eseguendo, anche in questo caso, il cast di ciascun oggetto ottenuto verso il tipo TreeViewItem, del quale vengono poi ottenute le proprietà, analizzate e, sulla base di queste, viene eseguita una nuova query per determinare e scrivere nel documento XML l’elenco dei vari siti/blog appartenenti a ciascuna categoria. I nodi del documento XML vengono così generati dinamicamente.

 

E’ così giunto il momento tanto atteso di eseguire la nostra applicazione. Premete, quindi, F5. Quando l’applicazione è in esecuzione, potete sfogliare la TreeView popolata con i vari siti/blog suddivisi per categorie, selezionare il blog di vostro interesse e vedere l’elenco degli ultimi post, come in figura:

 

 

 

Ora è chiaro il risultato dell’utilizzo dei DataTemplate nella ListView: per ciascun elemento, l’HyperLink ci permette di visualizzare il titolo del post e di cliccare sul collegamento per aprire il post selezionato nel browser predefinito. I blog di VB T&T non mostrano la categoria, al contrario di altri ma vi basta sfogliare i vari siti per vedere cosa accade. Ora, ipotizziamo di voler aggiungere un nuovo sito al nostro elenco. Dalla ComboBox, selezionate Visual Basic Tips & Tricks dall’elenco. Nel campo Author digitate Gianluca Cannalire, nel campo Url digitate http://community.visual-basic.it/Gianluca/rss.aspx, quindi fate clic su Add new feed. Come si osserva dalla figura seguente, il nuovo blog viene correttamente aggiunto alla categoria specificata ed è pronto per essere sfogliato:

 

 

 

Abbiamo così a disposizione un’applicazione smart client in grado di consentirci di stare sempre aggiornati con le novità provenienti dai maggiori siti di development e blog delle maggiori community italiane su tecnologia Microsoft .NET, che offre l’utilità di visualizzare elenchi di post e di aprire solo quelli che ci interessano effettivamente, piuttosto che aprire ogni volta tutti i siti o rischiando di dimenticarne qualcuno.

 

Il presente post si conclude qui, con l’applicazione perfettamente funzionante e realizzata con Microsoft Visual Basic 2008. Ma il tutorial proseguirà, con la spiegazione dell’utilizzo di Microsoft Expression Blend 2 per lo styling dei controlli WPF utilizzati.

 

Alessandro

Print | posted on domenica 16 novembre 2008 19:02 | Filed Under [ .NET Framework Visual Basic Visual Studio 2008 Windows Presentation Foundation LINQ ]

Powered by:
Powered By Subtext Powered By ASP.NET