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

WPF: esempio 'master-details' con una DataGrid personalizzata in VB 2008

Nel precedente post abbiamo creato un piccolo esempio di tipo “master-details” nell’ambito di un’applicazione WPF creata con Visual Basic 2008, in cui viene data la possibilità di visualizzare e modificare gli ordini riferibili a un determinato cliente sfruttando il nuovo controllo DataGrid offerto dal WPF Toolkit.

 

In quel caso, abbiamo lasciato invariate le impostazioni di default della griglia, con particolare riferimento al layout: generazione automatica delle colonne (quindi alcune non sono di interesse) e formattazione dei contenuti come testo indipendentemente dal loro tipo.

 

Tuttavia, la DataGrid permette di personalizzare il modo in cui i dati vengono presentati. E’ infatti possibile definire colonne personalizzate e il relativo Template. La DataGrid offre alcuni template nativi:

 

·         DataGridTextColumn, adatto alla visualizzazione/editing di testo;

·         DataGridCheckBoxColumn, adatto alla presentazione di valori booleani mediante CheckBox;

·         DataGridComboBoxColumn, che consente di selezionare il valore da assegnare a una cella mediante un elenco presente in una ComboBox;

·         DataGridHyperLinkColumn, che permette di assegnare un collegamento ipertestuale al testo indicato nella cella;

·         DataGridTemplateColumn, che consente di definire il proprio template personalizzato, ad esempio aggregando una serie di controlli WPF per ottenere l’aspetto desiderato.

 

Il layout standard della DataGrid utilizza, in buona sostanza, DataGridTextColumn come default e questa non è sempre la scelta più adatta. Per esempio, potrebbe essere utile utilizzare un controllo DatePicker per modificare la data di un ordine. Per fare questo, è quindi necessario definire template personalizzati.

 

Riprendiamo l’esempio visto la scorsa volta (scaricabile da qui) e facciamo delle modifiche. In primo luogo, mostreremo solo alcune colonne della tabella Orders. Inoltre formatteremo la valuta con idoneo simbolo, consentiremo la ricerca su Live Maps delle località destinatarie delle spedizioni e consentiremo di specificare la data degli ordini utilizzando un DatePicker.

 

Dopo aver aperto il progetto, ci spostiamo nell’editor di codice XAML. Innanzitutto, modifichiamo il codice dichiarativo della DataGrid nel modo seguente:

 

        <my:DataGrid Name="ProductsDataGrid" Grid.Row="1" IsSynchronizedWithCurrentItem="True"

                     AutoGenerateColumns="False" AlternatingRowBackground="Azure"

                     ItemsSource="{Binding}" >

 

È importante notare che la proprietà AutoGenerateColumns è ora impostata su False. Le colonne vanno inserite all’interno di un elemento chiamato DataGrid.Columns. La prima colonna mostrerà l’OrderID, l’identificativo:

 

            <my:DataGrid.Columns>

                <my:DataGridTextColumn Header="Order ID" Binding="{Binding Path=OrderID}"/>

 

La proprietà Header stabilisce l’intestazione di colonna, mentre la proprietà Binding determina l’oggetto che deve essere collegato al controllo. In questo caso si tratta di testo, di conseguenza abbiamo utilizzato una DataGridTextColumn.

 

Ora, vogliamo creare una colonna per mostrare la proprietà OrderDate, la data dell’ordine. Dobbiamo utilizzare un oggetto DataGridTemplateColumn per poter definire un DataTemplate personalizzato per le celle di questa colonna. La cosa interessante è che possiamo definire il comportamento sia per la visualizzazione dei dati che per la modifica. Per esempio, per visualizzare i dati potremmo utilizzare un TextBlock, mentre per la modifica potremmo utilizzare un DatePicker. Ecco il codice di implementazione della colonna:

 

                <my:DataGridTemplateColumn Header="Order Date">

                    <my:DataGridTemplateColumn.CellTemplate>

                        <DataTemplate>

                            <TextBlock Text="{Binding Path=OrderDate, StringFormat='D'}"/>

                        </DataTemplate>

                    </my:DataGridTemplateColumn.CellTemplate>

                    <my:DataGridTemplateColumn.CellEditingTemplate>

                        <DataTemplate>

                            <my:DatePicker SelectedDate="{Binding Path=OrderDate, Mode=TwoWay, StringFormat='D'}"/>

                        </DataTemplate>

                    </my:DataGridTemplateColumn.CellEditingTemplate>

                </my:DataGridTemplateColumn>

 

In parole povere, l’oggetto DataGridTemplateColumn.CellTemplate permette di specificare le modalità con cui i dati debbano essere visualizzati. In questo caso è sufficiente utilizzare un TextBlock, la cui proprietà StringFormat permette di formattare il testo contenuto secondo il formato di data estesa. L’oggetto DataGridTemplateColumn.CellEditingTemplate, invece, ci consente di specificare le modalità per la modifica dei dati. Utilizzando un DatePicker possiamo consentire all’utente di selezionare le date mediante uno specifico controllo, piuttosto che scriverle a mano. Il binding si fa sulla proprietà SelectedDate in modalità TwoWay (questo assicura il corretto “allineamento” tra interfaccia e dati sottostanti). E’ possibile specificare anche qui la proprietà StringFormat, di modo che non ci siano variazioni tra modo visualizzazione e modo di editing. Cool! J

 

La colonna successiva che ci interessa è quella denominata Freight e che rappresenta il costo del trasporto. Più che altro, ci interessa per capire come possiamo formattare i dati secondo la visualizzazione in valuta:

 

                <my:DataGridTextColumn Header="Freight" Binding="{Binding Path=Freight, StringFormat='c'}"/>

 

L’ultima colonna che vogliamo implementare riguarda la città di destinazione delle spedizioni. Possiamo far sì che il nome della città sia mostrato come HyperLink e costruire poi, nel code-behind, una stringa da passare a Live Maps:

 

                <my:DataGridHyperlinkColumn Header="Ship Country" Binding="{Binding Path=ShipCountry}">

                    <my:DataGridHyperlinkColumn.ElementStyle>

                        <Style TargetType="TextBlock">

                            <EventSetter Event="Hyperlink.RequestNavigate" Handler="OnHyperLinkClicked" />

                        </Style>

                    </my:DataGridHyperlinkColumn.ElementStyle>

                </my:DataGridHyperlinkColumn>

            </my:DataGrid.Columns>

           

        </my:DataGrid>

 

Oltre al tipo di colonna utilizzato, notate la specifica di un ElementStyle grazie al quale possiamo specificare eventi da intercettare (in questo caso RequestNavigate). Passando al code-behind, possiamo lasciare invariato il codice esistente ed aggiungere solo un gestore per l’evento RequestNavigate:

 

    Private Sub OnHyperlinkClicked(ByVal sender As Object, _

                                   ByVal e As RequestNavigateEventArgs)

 

        'La proprietà e.Uri contiene il testo dell'HyperLink,

        'nel nostro caso il nome della città

        Dim link As New Uri("http://maps.live.com/?q=" + _

                            e.Uri.ToString + "&mkt=it-IT&FORM=BYRE")

 

        Process.Start(link.ToString)

    End Sub

 

Ora proviamo ad avviare l’applicazione di esempio; la seguente figura esemplifica il risultato:

 

 

 

Possiamo osservare che i campi inerenti somme di denaro vengono formattati con i simboli di valuta e che la modifica dei campi data può avvenire mediante DatePicker, quindi con un click di mouse invece che scrittura manuale. Infine, il campo inerente il nome della città è mostrato come collegamento ipertestuale; cliccando su tale HyperLink viene avviata una ricerca della località su Internet. Un approccio decisamente diverso e più user friendly rispetto a quello che abbiamo visto nel primo post!

 

Da ultimo, voglio segnalarvi la possibilità di gestire a design-time le varie colonne. Se assegnate una sorgente dati alla DataGrid direttamente nello XAML (ad esempio tramite un ObjectDataProvider), è possibile sfruttare il designer di Visual Studio (finestra Proprietà -> Columns). La seguente figura mostra la finestra di gestione delle colonne:

 

 

La nuova versione del progetto è scaricabile da questo indirizzo dell’area download di Visual Basic Tips & Tricks.

 

Alessandro

Print | posted on venerdì 3 aprile 2009 20:19 | Filed Under [ Visual Basic Windows Presentation Foundation ]

Powered by:
Powered By Subtext Powered By ASP.NET