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: ListBox con posizionamento dinamico degli elementi

Un mio amico mi ha posto un interessante quesito su WPF: data una ListBox popolata a run-time con dei dati, quindi con numero di elementi non conosciuto a priori, come è possibile far sì che al ridimensionamento della finestra (e quindi al variare delle dimensioni della ListBox) gli elementi vengano allineati dinamicamente all'interno della ListBox stessa?

Supponiamo di voler creare una banale applicazione che mostri l'elenco dei processi attivi sul sistema, affiancando al nome di ciascun processo una bitmap.

La ListBox è uno di quei controlli WPF che permette di definire l'ItemTemplate, ossia quell'insieme di elementi semplici che compone e costituisce il singolo elemento. Ciò premesso, possiamo definire il DataTemplate per ciascun ListBoxItem ad esempio all'interno di uno stile, per praticità, nel modo che segue:

    <Window.Resources>

       

        <!--Definisco uno stile-->

        <Style x:Key="MyBoxStyle" TargetType="ListBox">

            <!-- Per ciascun Item, definisco il template-->

            <Setter Property="ItemTemplate">

                <Setter.Value>

                    <DataTemplate>

                        <StackPanel Orientation="Horizontal" Margin="5">

                            <!-- Collego il testo alla proprietà della collezione di mio interesse,

                                 in questo caso l'elenco dei processi attivi-->

                            <TextBlock Text="{Binding Path=ProcessName}" FontSize="14" Margin="3"/>

                            <Image Width="16" Height="16" Source="openHs.png"

                                   Stretch="UniformToFill" Margin="3"/>

                        </StackPanel>

                    </DataTemplate>

                </Setter.Value>

            </Setter>

Questo, però, definisce solo come deve essere presentato il contenuto di ciascun ListBoxItem, ma non il relativo posizionamento. Esiste un'altra proprietà, chiamata ItemsPanel, che definisce proprio questo. Per default, si tratta di uno StackPanel ma può essere modificata con un WrapPanel, che è il contenitore adatto a realizzare ciò che ci serve. Proseguendo il codice di prima, possiamo scrivere quanto segue:

            <!--Utilizzo un WrapPanel, che manda a capo automaticamente i vari elementi

                a seconda della dimensione del controllo -->

            <Setter Property="ItemsPanel">

                <Setter.Value>

                    <ItemsPanelTemplate>

                        <WrapPanel />

                    </ItemsPanelTemplate>

                </Setter.Value>

            </Setter>

 

            <Setter  Property="ScrollViewer.HorizontalScrollBarVisibility"

                     Value="Disabled"/>

        </Style> 

    </Window.Resources>

L'ultimo step a livello di XAML è quello di dichiarare la ListBox:

    <Grid>

        <ListBox ItemsSource="{Binding}"

                 Name="List1" IsSynchronizedWithCurrentItem="True"

                 Style="{StaticResource MyBoxStyle}" >

        </ListBox>

    </Grid>

A run-time, il nostro controllo verrà popolato con il nome di ciascun processo attivo sul sistema. Ci basta invocare il metodo AsEnumerable nei confronti del ben noto Process.GetProcesses:

    Public Sub New()

 

        ' This call is required by the Windows Form Designer.

        InitializeComponent()

 

        ' Add any initialization after the InitializeComponent() call.

 

        Me.List1.ItemsSource = Process.GetProcesses.AsEnumerable

 

    End Sub

All'avvio dell'applicazione abbiamo qualcosa di simile:

Provando a ridimensionare la finestra, potrete vedere come i vari ListBoxItem vengano disposti in modo dinamico all'interno della ListBox:

Alessandro

Print | posted on giovedì 2 aprile 2009 20:46 | Filed Under [ Visual Basic Windows Presentation Foundation ]

Powered by:
Powered By Subtext Powered By ASP.NET