Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ListBox display error #18264

Open
Linlccc opened this issue Feb 20, 2025 · 3 comments
Open

ListBox display error #18264

Linlccc opened this issue Feb 20, 2025 · 3 comments
Labels

Comments

@Linlccc
Copy link

Linlccc commented Feb 20, 2025

Describe the bug

After quickly scrolling up and down in the ListBox, some extra display items appear mysteriously, as shown in the figure, such as 80 and 86.

Image

To Reproduce

ViewModel

public class TestViewModel : ViewModelBase
{
    public class MyClass(string text, bool isImage)
    {
        public string Text { get; set; } = text;

        // Load random exception image
        public Bitmap? Image { get; set; } = isImage ? new Bitmap("/Users/lin/Pictures/截屏与录制/2484ed39-3cf6-4393-8dc4-fddfcee410b3.png") : null;
    }

    public ObservableCollection<MyClass> List { get; set; }
    public MyClass SelectedItem { get; set; }

    public TestViewModel()
    {
        List = [];
        for (int i = 0; i < 300; i++)
        {
            List.Add(new MyClass($"测试{i}", i % 3 == 0));
        }
        SelectedItem = List[0];
    }
}

Backend code

private void ClipItem_OnPointerEntered(object? sender, PointerEventArgs e)
{
    if (sender is Control { Parent: ListBoxItem listBoxItem }) listBoxItem.IsSelected = true;
}

View

<ListBox Grid.Row="1" IsVisible="True" ItemsSource="{Binding List}" SelectedItem="{Binding SelectedItem}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border Background="Transparent" PointerEntered="ClipItem_OnPointerEntered">
                <Grid ColumnDefinitions="*,Auto" Margin="9,3">
                    <StackPanel>
                        <TextBlock Text="{Binding Text}" FontSize="12" />
                        <Image Source="{Binding Image}" />
                    </StackPanel>
                    <ContentControl Grid.Column="1" x:Name="itemRight" />
                </Grid>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Expected behavior

No abnormal display occurs

Avalonia version

11.2.3

OS

macOS

Additional context

No response

@Linlccc Linlccc added the bug label Feb 20, 2025
@maxkatz6
Copy link
Member

maxkatz6 commented Feb 20, 2025

Does it reproduce without selection on pointer over?
You can try to change this line:

-    if (sender is Control { Parent: ListBoxItem listBoxItem }) listBoxItem.IsSelected = true;
+    if (sender is Control { Parent: ListBoxItem listBoxItem }) listBoxItem.SetCurrentValue(ListBoxItem.IsSelectedProperty, true);

@Linlccc
Copy link
Author

Linlccc commented Feb 20, 2025

Does it reproduce without selection on pointer over? You can try to change this line:

  • if (sender is Control { Parent: ListBoxItem listBoxItem }) listBoxItem.IsSelected = true;
  • if (sender is Control { Parent: ListBoxItem listBoxItem }) listBoxItem.SetCurrentValue(ListBoxItem.IsSelectedProperty, true);

The error display still occurs after the modification.

@AVVI94
Copy link

AVVI94 commented Feb 22, 2025

I'm experiencing similar issues with the ListBox and its default VirtualizingStackPanel. My list items have a fixed height of 67, but issues arise when scrolling quickly—items sometimes fail to render properly, and the up/down arrows in the scrollbar are misaligned.

I'm noticing this behavior since Avalonia 11.0.10. These render/scroll errors can be easily fixex by switching to regular stack panel as ItemsPanel but then the rendering performance gets really bad with higher number of items.

In last 5 seconds in the attached video I'm not even scrolling, I just move the mouse in the panel 😄

Record.2025-02-23.003540.mp4

Here is my XAML for the view:

<ListBox Grid.Row="5"
         Grid.Column="1"
         Grid.ColumnSpan="2"
         Padding="0,0,24,0"
         Classes="no-indicator no-default-margin no-item-bg"
         IsVisible="{Binding !Loading}"
         ItemsSource="{Binding Requests}"
         SelectedItem="{Binding SelectedRequest}">
	<ListBox.ItemTemplate>
		<DataTemplate x:DataType="vm:RequestListItemViewModel">
			<Border x:Name="ItemBorderRoot"
			        Height="67"
			        Margin="0,0,0,12"
			        Background="{DynamicResource Surface}"
			        Classes.error="{Binding IsError}"
			        Classes.success="{Binding IsSuccess}"
			        CornerRadius="2">
				<Border.Transitions>
					<Transitions>
						<BrushTransition Property="Background"
						                 Duration="0:0:0.185" />
					</Transitions>
				</Border.Transitions>
				<Grid VerticalAlignment="Center"
				      ColumnDefinitions="auto,8,*"
				      RowDefinitions="auto,auto">
					<TextBlock Grid.Row="0"
					           Grid.Column="0"
					           VerticalAlignment="Center"
					           Classes="p blue"
					           FontWeight="DemiBold"
					           Text="{Binding RequestId, Converter={x:Static conv:Converters.RequestIdConverter}}" />
					<TextBlock Grid.Row="1"
					           Grid.Column="0"
					           Grid.ColumnSpan="3"
					           Classes="p blue fs-8"
					           Text="{Binding Name}" />
					<TextBlock x:Name="ProcessingStatus"
					           Grid.Row="0"
					           Grid.Column="2"
					           HorizontalAlignment="Right"
					           VerticalAlignment="Center"
					           Classes="p fs-8"
					           Text="{ica:Loc {Binding ProcessingStatus, Converter={x:Static conv:Converters.RequestStepToStrKey}}}" />
				</Grid>
			</Border>
		</DataTemplate>
	</ListBox.ItemTemplate>
	<ListBox.Styles>
		<Style Selector="ListBoxItem">
			<Setter Property="Padding" Value="0" />
			<Setter Property="Background" Value="Transparent" />
			<Setter x:DataType="vm:RequestListItemViewModel" Property="IsVisible" Value="{Binding IsVisible}" />

			<Style Selector="^ Border#ItemBorderRoot">
				<Setter Property="BorderThickness" Value="2" />
				<Setter Property="Padding" Value="16 0 16 0" />
			</Style>

			<Style Selector="^:not(:selected) > Border#ItemBorderRoot">
				<Style Selector="^.error:not(:pointerover)">
					<Setter Property="BorderBrush" Value="{DynamicResource Error.Foreground}" />
					<Setter Property="BorderThickness" Value="3 0 0 0" />
					<Setter Property="Padding" Value="15 0 18 0" />
				</Style>
				<Style Selector="^.success:not(:pointerover)">
					<Setter Property="BorderBrush" Value="{DynamicResource Primary}" />
					<Setter Property="BorderThickness" Value="3 0 0 0" />
					<Setter Property="Padding" Value="15 0 18 0" />
				</Style>
			</Style>

			<Style Selector="^:pointerover:not(:selected) > Border#ItemBorderRoot">
				<Setter Property="BorderThickness" Value="2" />
				<Setter Property="BorderBrush" Value="{DynamicResource Accent}" />
				<Setter Property="Background" Value="{DynamicResource Surface}" />
			</Style>

			<Style Selector="^:selected">
				<Style Selector="^ > Border#ItemBorderRoot">
					<Setter Property="BorderThickness" Value="2" />
					<Setter Property="BorderBrush" Value="{DynamicResource Text.Standard}" />
					<Setter Property="Background" Value="{DynamicResource Surface.Smoky}" />
				</Style>
				<Style Selector="^ TextBlock#ProcessingStatus">
					<Setter Property="Foreground" Value="{DynamicResource Text.Standard}" />
				</Style>
			</Style>
		</Style>
		<Style Selector="ListBoxItem:nth-last-child(1)">
			<Setter Property="Padding" Value="0 0 0 12" />
		</Style>
	</ListBox.Styles>
</ListBox>

And the no-indicator no-default-margin no-item-bg styles:

<Styles xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Design.PreviewWith>
        <Border Padding="20">
            <!--  Add Controls for Previewer Here  -->
        </Border>
    </Design.PreviewWith>

    <Style Selector=":is(ListBox).no-indicator ListBoxItem">
        <Style Selector="^:selected">
            <Style Selector="^ Rectangle#SelectionIndicator">
                <Setter Property="IsVisible" Value="False" />
                <Setter Property="Width" Value="0" />
            </Style>
        </Style>
    </Style>
    <Style Selector=":is(ListBox).no-item-padding ListBoxItem">
        <Setter Property="Padding" Value="0" />
    </Style>
    <Style Selector=":is(ListBox).no-default-margin ListBoxItem">
        <Setter Property="Margin" Value="0" />
        <Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
            <Setter Property="Margin" Value="0" />
        </Style>
    </Style>
    <Style Selector=":is(ListBox).no-item-bg">
        <Style Selector="^ ListBoxItem /template/ ContentPresenter#PART_ContentPresenter, ^ ListBoxItem:pointerover /template/ ContentPresenter#PART_ContentPresenter, ^ ListBoxItem:selected /template/ ContentPresenter#PART_ContentPresenter">
            <Setter Property="Background" Value="{x:Null}" />
        </Style>
    </Style>
</Styles>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants