Skip to content

ScrollViewer or ItemsRepeater does not render items added to the top #28

@Hunv

Description

@Hunv

Describe the bug

I have this:

<ScrollViewer
  ScrollViewer.VerticalScrollBarVisibility= "Auto"
  Grid.Row= "0"
  >
  <cntrl:ItemsRepeater
      ItemsSource = "{Binding MyItemList}"
      Background= "{DynamicResource SiteBackgroundBrush}"
    >
    <ItemsRepeater.ItemTemplate >
      <DataTemplate DataType= "m:MyModel" >
        <Border
          BorderThickness= "2"
          CornerRadius= "5"
          BorderBrush= "{DynamicResource ItemBackgroundBrush}"
          Background= "{DynamicResource ItemBackgroundBrush}"
          Margin= "5,5,5,0"
          >
          <Grid Margin= "0,5,0,0" >
            ...            
          </Grid>
        </Border>
      </DataTemplate>
    </ItemsRepeater.ItemTemplate>
  </cntrl:ItemsRepeater>
</ScrollViewer>

The MyItemList is an ObservableCollection.
When I add a new Item to the Top of the list via MyItemList.Insert(0, ...) and run a this.RaisePropertyChanged(nameof(MyItemList));, the space of the new item in the ItemsRepeater is used but the item itself is not rendered. This does not happen from the very beginning but after some (not so long) time. I think shortly after when the first items runs out of the visible part of the Window.
If I scroll just a pixel in the ScrollViewer, everything is where and how it should be immediately.
This does not happen, if the ScrollViewer is not involved.

This is how it looks like:
image

To Reproduce

Create a new Avalonia Project from scratch with Desktop enabled. Leave everything else at default.
Make the following changes:

  1. Add the Avalonia.ItemsRepeater Nuget to the main project
  2. Replace code in MainViewModel.cs with this:
using System.Collections.ObjectModel;
using System;
using ReactiveUI;

namespace AvaloniaApplication1.ViewModels;

public class MainViewModel : ViewModelBase
{
    public ObservableCollection<MyModel> MyItemList { get; set; } = new ObservableCollection<MyModel>();
    private readonly System.Timers.Timer _TmrDisruptionUpdate = new(1000);

    public MainViewModel() 
    { 
        MyItemList.Add(new MyModel() { Text = "foobar"});
        MyItemList.Add(new MyModel() { Text = "Hello World" });
        MyItemList.Add(new MyModel() { Text = "John Doe" });
        MyItemList.Add(new MyModel() { Text = "xxxxx" });

        _TmrDisruptionUpdate.Elapsed += _TmrDisruptionUpdate_Elapsed;
        _TmrDisruptionUpdate.Start();
    }

    private void _TmrDisruptionUpdate_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
    {
        MyItemList.Insert(0, new MyModel() { Text = DateTime.Now.ToString() });        
        this.RaisePropertyChanged(nameof(MyItemList));
    }
}
  1. Create a new class called MyModel.cs with the following content:
namespace AvaloniaApplication1.ViewModels
{
    public class MyModel
    {
        public string Text { get; set; }
    }
}
  1. Edit the MainView.axaml as follows:
<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:vm="clr-namespace:AvaloniaApplication1.ViewModels"
             xmlns:cntrl="using:Avalonia.Controls"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="AvaloniaApplication1.Views.MainView"
             x:DataType="vm:MainViewModel">
  
  <ScrollViewer
    ScrollViewer.VerticalScrollBarVisibility="Auto"
    >
    <cntrl:ItemsRepeater
        ItemsSource="{Binding MyItemList}"
        Background="#222222"
        >
      <ItemsRepeater.ItemTemplate>
        <DataTemplate DataType="vm:MyModel">
          <Border
            BorderThickness="2"
            CornerRadius="5"
            BorderBrush="#888888"
            Background="#888888"
            Margin="5,5,5,0"
            >
            <Grid Margin="0,20">
              <TextBlock
                Text="{Binding Text}"
                />
            </Grid>
          </Border>
        </DataTemplate>
      </ItemsRepeater.ItemTemplate>
    </cntrl:ItemsRepeater>
  </ScrollViewer>
</UserControl>

I create a sample project with the things above:
ScrollViewerRenderIssue.zip

Expected behavior

Also later added items are rendered as the first items that were added.

Avalonia version

11.1.4

OS

Windows

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions