ItemsControl, VirtualizingStackPanel e l'altezza ScrollViewer
-
21-09-2019 - |
Domanda
Voglio visualizzare un elenco importante di elementi utilizzando un ItemsControl.
Il motivo per cui sto usando un ItemsControl è che il DataTemplate è molto più complessa l'applicazione su cui sto lavorando. Il codice di esempio fornito solo riflette il problema di dimensionamento che ho
Vorrei:
- ItemsControl da virtualizzato, perché ci sono molti elementi da visualizzare
-
la sua dimensione di espandere il suo contenitore padre automaticamente (la griglia)
<Grid> <ItemsControl x:Name="My" ItemsSource="{Binding Path=Names}"> <ItemsControl.Template> <ControlTemplate> <StackPanel> <StackPanel> <TextBlock Text="this is a title" FontSize="15" /> <TextBlock Text="This is a description" /> </StackPanel> <ScrollViewer CanContentScroll="True" Height="400px"> <VirtualizingStackPanel IsItemsHost="True" /> </ScrollViewer> </StackPanel> </ControlTemplate> </ItemsControl.Template> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid>
Il codice è dietro:
public partial class Page1: Page
{
public List<string> Names { get; set; }
public Page1()
{
InitializeComponent();
Names = new List<string>();
for(int i = 0; i < 10000; i++)
Names.Add("Name : " + i);
My.DataContext = this;
}
}
Come forzo l'altezza ScrollViewer a 400px, la virtualizzazione ItemsControl funziona come mi aspetto. L'ItemsControl visualizza l'elenco molto rapidamente, indipendentemente dal numero di elementi che contiene
Tuttavia, se tolgo height = "400px", la lista si espanderà la sua altezza per visualizzare l'intera lista, a prescindere la sua altezza contenitore padre. Peggio:. Appare dietro il suo contenitore
Mettere uno ScrollViewer intorno al ItemsControl dà il risultato visivo previsto, ma la virtualizzazione va via e la lista richiede troppo tempo per visualizzare.
Come posso ottenere sia l'espansione automatica altezza e la virtualizzazione del mio ItemsControl?
Soluzione
Il problema è nel ItemsControl.Template: si utilizza StackPanel lì, che dà i suoi figli tanto in altezza come vogliono. Sostituire a qualcosa come
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel>
<TextBlock Text="this is a title" FontSize="15" />
<TextBlock Text="This is a description" />
</StackPanel>
<ScrollViewer CanContentScroll="True" Grid.Row="1">
<VirtualizingStackPanel />
</ScrollViewer>
</Grid>
E dovrebbe funzionare bene.
Speranza che aiuta.