Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1908, 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

Disabilita cookie ShinyStat

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 4.5: novità nel VirtualizingStackPanel

Come sapete, il VirtualizingStackPanel è uno speciale contenitore che alcuni controlli WPF utilizzano, per default, per presentare liste di dati (es. ListBox, ListView, DataGrid).

Come infatti il nome lascia intendere, questo contenitore è in grado di virtualizzare la collection associata al controllo, di modo che la combinazione tra scorrimento e caricamento in memoria sia il più possibile "responsive" e ottimizzata per collection molto grandi.

In WPF 4.5 il VirtualizingStackPanel subisce due ulteriori miglioramenti:

  • nell'architettura: by design il controllo è ora più performante di prima
  • nella gestione: viene introdotta la proprietà ScrollUnit, che accetta due valori: Item e Pixel. Item fa si che lo scrolling visualizzi solo gli elementi completamente virtualizzati, quindi fa sì che l'intero elemento sia visibile. Pixel, invece, scrolla normalmente mostrando un po' alla volta l'elemento in via di virtualizzazione

Ho fatto un po' di test e l'uso di ScrollUnit lo ritengo abbastanza estremo. Nel senso che le performance del VirtualizingStackPanel sono ottime anche con 500000 istanze di oggetti.

Ho questo codice XAML:

    <Grid DataContext="{Binding}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <ListBox 
                 VirtualizingPanel.ScrollUnit="Item" Grid.Row="0"
                 ScrollViewer.CanContentScroll="True"
                 ItemsSource="{Binding}" Name="VirtualizingBox" ScrollViewer.VerticalScrollBarVisibility="Auto">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="Black" CornerRadius="5" BorderThickness="3" Margin="40">
                        <StackPanel Background="LightBlue">
                            <TextBlock  Text="{Binding FirstName}" Height="40" FontSize="30" Width="250"/>
                            <TextBlock  Text="{Binding LastName}" Height="40" FontSize="30" Width="250"/>
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Content="Load" Name="LoadButton" Click="LoadButton_Click" Grid.Row="1"/>
    </Grid>

Ho una ListBox che riceverà dei dati a runtime, per la quale ho esplicitato la virtualizzazione (è by default, ma non guasta...) e la visualizzazione di scroll bar. Ho anche impostato la attached property ScrollUnit del panel virtualizzante (che parolona ). I due TextBlock sono collegati in binding a una ipotetica classe Contact o altro nome. Ho, inoltre, ipoteticamente creato una classe Contacts che è di tipo ObservableCollection(Of Contact). Se consideriamo ora il seguente codice:

    Dim c As Contact
    Dim cs As New Contacts
    Private Sub LoadButton_Click(sender As Object, e As RoutedEventArgs)
        Dispatcher.InvokeAsync(Sub()
                                   For i = 1 To 100000
                                       c = New Contact
                                       c.Age = 34
                                       c.FirstName = "Nome " + i.ToString
                                       c.LastName = "Cognome " + i.ToString
                                       cs.Add(c)
                                   Next
 
                                   For Each item In cs
                                       Me.VirtualizingBox.Items.Add(item)
                                   Next
                               End Sub)
 
    End Sub

sto generando 100000 istanze della classe Contact e potrò verificare da solo l'opera di virtualizzazione compiuta dal VirtualizingStackPanel a runtime.

Quello che però è interessante notare è anche un nuovo metodo della classe Dispatcher, chiamato InvokeAsync, che consente di eseguire in modo asincrono un attività di tipo Action, rappresentata in questo caso da una statement lambda la quale si occupa di generare le istanze della classe.

Questa modalità asincrona consente un'ulteriore ottimizzazione del caricamento, non ci sono problemi di cross-thread perchè l'attività viene eseguita nello stesso thread ed è, inoltre, una delle altre novità di WPF 4.5.

Alessandro

Print | posted on martedì 21 febbraio 2012 20:49 | Filed Under [ Windows Presentation Foundation ]

Powered by:
Powered By Subtext Powered By ASP.NET