2010-08-06 9 views
6

Sto provando a creare un elenco a scorrimento di blocchi di testo abbastanza grandi. Voglio che ci sia una barra di scorrimento verticale per mostrarli tutti e, se superano una certa dimensione, voglio che mostrino un'ellissi. In realtà, tutto questo funziona abbastanza bene.Utilizzo della virtualizzazione dell'interfaccia utente con ItemsControl in Silverlight

Ho il seguente XAML Silverlight:

<Grid x:Name="LayoutRoot" MaxWidth="500" MinWidth="100" 
    MaxHeight="500" MinHeight="100"> 
    <Grid.DataContext> 
     <app:MainPageViewModel/> 
    </Grid.DataContext> 
    <ScrollViewer> 
    <ItemsControl ItemsSource="{Binding TextItems}" Margin="0,20,0,20"> 
     <ItemsControl.ItemTemplate><DataTemplate> 
      <Border MaxHeight="175" Margin="0,0,0,18" CornerRadius="5"> 
       <TextBlock Margin="2" TextTrimming="WordEllipsis" 
        TextWrapping="Wrap" Text="{Binding}"/> 
      </Border> 
     </DataTemplate></ItemsControl.ItemTemplate> 
    </ItemsControl> 
    </ScrollViewer> 
</Grid> 

mio problema è che questa disposizione non fa uso di virtualizzazione dell'interfaccia utente, ad esempio con un VirtualizingStackPanel. Quindi è piuttosto lento. Qual è il modo migliore per ottenere la virtualizzazione dell'interfaccia utente in questo layout? Ho provato una mezza dozzina di modi diversi e niente ha funzionato così bene.

Sono riuscito a farlo funzionare in un ListBox perché sembra supportare la virtualizzazione fuori dalla scatola. Tuttavia, preferirei usare ItemsControl perché non voglio che queste cose siano selezionabili, e non voglio lo stile che accompagna un ListBox.

Questo in Silverlight 4.

risposta

15

ci sono alcune cose che dovete fare per fare questo lavoro.

  1. Impostare l'ItemsPanelTemplate per vostro ItemsControl ad un VirtualizingStackPanel.
  2. Incorporate ScrollViewer all'interno di un ControlTemplate per il vostro ItemsControl anziché solo avvolgendolo intorno all'esterno.
  3. Assicurarsi che ItemsControl abbia un'altezza fissa in modo che il sistema di layout possa calcolare quanti elementi deve riempire il viewport. (Sembra che si sta già facendo questo mettendo ItemsControl in una griglia - che permetterà al sistema di layout per determinare l'altezza alloted per il controllo)

Ecco l'esempio più semplice che potrebbe venire con questo lavoro :

<ItemsControl ItemsSource="{Binding TextItems}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <VirtualizingStackPanel /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.Template> 
      <ControlTemplate TargetType="ItemsControl"> 
       <Border> 
        <ScrollViewer> 
         <ItemsPresenter/> 
        </ScrollViewer> 
       </Border> 
      </ControlTemplate> 
     </ItemsControl.Template> 
    </ItemsControl> 
+0

Che ha funzionato come un fascino Steve. Quindi la differenza principale tra la tua soluzione e quello che stavo cercando di fare è che hai usato ItemsControl.Template per aggiungerlo nel ScrollViewer, mentre stavo solo cercando di mettere un ScrollViewer all'esterno del controllo. Puoi spiegare perché il tuo funziona e quello che stavo cercando di fare non lo fa? Potrebbe aiutarmi a capire meglio la soluzione. – RationalGeek

+1

Grande, felice ha funzionato per te. In pratica, ciò che accade è che se metti un ScrollViewer all'esterno di ItemsControl, il motore di layout renderà l'intero ItemsControl - genererà contenitori di oggetti per tutti gli elementi nel controllo. ScrollViewer limita la vista a una piccola parte di ItemsControl ma l'intero ItemsControl con tutti gli elementi esiste in memoria. Il secondo modo, inserendo ScrollViewer all'interno del modello, dà a ItemsControl la possibilità di limitare il numero di contenitori oggetto creati, ma creerà solo abbastanza per riempire lo spazio disponibile. –

+0

Ha senso. Grazie ancora! – RationalGeek

Problemi correlati