ItemsControl, VirtualizandostackPanel e Altura do ScrollViewer
-
21-09-2019 - |
Pergunta
Quero exibir uma lista importante de itens usando um itemsControl.
A razão pela qual estou usando um itemsControl é que o DataTemplate é muito mais complexo no aplicativo em que estou trabalhando: o código de amostra fornecido apenas reflete o problema de dimensionamento que tenho.
Eu gostaria :
- o itemsControl a ser virtualizado porque há muitos itens a serem exibidos
seu tamanho para expandir para seu contêiner pai automaticamente (a grade)
<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>
O código por trás é:
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;
}
}
À medida que forço a altura do scrollViewer a 400px, a virtualização do itemSControl funciona como eu espero: o itemsControl exibe a lista muito rapidamente, independentemente de quantos itens ele contém.
No entanto, se eu remover altura = "400px", a lista expandirá sua altura para exibir a lista inteira, independentemente da altura do contêiner pai. Pior: parece atras do seu recipiente.
Colocar um scrollViewer em torno do itemsControl fornece o resultado visual esperado, mas a virtualização desaparece e a lista leva muito tempo para ser exibida.
Como posso obter a expansão automática da altura e a virtualização do meu itemsControl?
Solução
O problema está no itemsControl.template: você usa o Stackpanel lá, o que dá a seus filhos o máximo que eles desejam. Substitua -o por algo como
<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 deve funcionar bem.
Espero que ajude.