ItemsControl, VirtualizingStackPanel и ScrollViewer height

Я хочу отобразить важный список элементов с помощью ItemsControl.

Причина, по которой я использую ItemsControl, заключается в том, что DataTemplate намного сложнее в приложении, над которым я работаю: предоставленный образец кода отражает только мою проблему с размером.

Я бы предпочел :

  • ItemsControl должен быть виртуализирован, потому что есть много элементов для отображения
  • его размер автоматически расширяется до родительского контейнера (сетка)

    <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>
    

Код позади:

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;
    }
}

Когда я устанавливаю высоту ScrollViewer на 400 пикселей, виртуализация ItemsControl работает так, как я ожидал: ItemsControl отображает список очень быстро, независимо от того, сколько элементов он содержит.

Однако, если я удалю Height = "400px", список расширит свою высоту, чтобы отобразить весь список, независимо от высоты его родительского контейнера. Хуже того: он появляется позади своего контейнера.

Размещение средства просмотра прокрутки вокруг ItemsControl дает ожидаемый визуальный результат, но виртуализация исчезает, и для отображения списка требуется слишком много времени.

Как я могу добиться как автоматического увеличения высоты, так и виртуализации моего ItemsControl?


person Community    schedule 16.10.2009    source источник


Ответы (1)


Проблема в ItemsControl.Template: вы используете там StackPanel, что дает ее детям столько высоты, сколько они хотят. Замени его на что-то вроде

<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>

И должно работать нормально.

Надеюсь, поможет.

person Community    schedule 16.10.2009