Search code examples
c#avaloniauiavalonia

AvaloniaUI ItemsControl Virtualization


I am attempting to display items in an ItemsControl that is 4 columns wide (the amount of columns is arbitrary right now) while supporting virtualization. I know that I can use a VirtualizingStackPanel as my ItemsPanelTemplate, but that causes my ItemsControl to display a single column of my data instead of 4 columns.

Is there any way to have my ItemsControl display its contents in a grid instead of a stack while still supporting virtualization?

I currently have the following code:

`<ScrollViewer Height="800">
    <ItemsControl ItemsSource="{Binding Monitors}" >
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="4"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border Background="#102a43" CornerRadius="20" Margin="10 5 10 5">
                    <Grid ColumnDefinitions="125, 125, 75, 75">
                        <TextBlock Grid.Column="0" Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        <TextBlock Grid.Column="1" Text="78C" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        <TextBox Grid.Column="2" Text="-57C" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        <TextBox Grid.Column="3" Text="129C" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    </Grid>
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</ScrollViewer>`

I've played around with trying to put my DataTemplate contents inside of a VirtualizingStackPanel but that caused my ItemsControl items to not display at all.

I'm sure I'm missing a foundational concept when it comes to using virtualization with a ItemsControl. What am I missing when it comes to properly using virtualization?


Solution

  • You can use ItemsRepeater from Avalonia.Controls.ItemsRepeater NuGet package. It has UniformGridLayout, which has virtualization out of the box. Something like this:

                        <ItemsRepeater ItemsSource="{Binding Monitors}" >
                        <ItemsRepeater.Layout>
                            <UniformGridLayout
                                MaximumRowsOrColumns="4"/>
                        </ItemsRepeater.Layout>
                      <ItemsRepeater.ItemTemplate>
                        <DataTemplate>
                          <Border Background="#102a43" CornerRadius="20" Margin="10 5 10 5">
                            <Grid ColumnDefinitions="125, 125, 75, 75">
                              <TextBlock Grid.Column="0" Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                              <TextBlock Grid.Column="1" Text="78C" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                              <TextBox Grid.Column="2" Text="-57C" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                              <TextBox Grid.Column="3" Text="129C" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            </Grid>
                          </Border>
                        </DataTemplate>
                      </ItemsRepeater.ItemTemplate>
                    </ItemsRepeater>