locked
Why are down arrow and up arrow REALLY SLOW for Listbox? RRS feed

  • Question

  • I have a listbox that has a LOT of items. (I know, I shouldn't do that...)

    There are something like 65000+ items.  If the list is 10,000 or so items, it works surprisingly well.

    But once it gets to be about 20,000 or more, it slows down.  And when you have 65000+ and when you select an item in the list and do a down arrow, it takes about 2 seconds.

    I don't know why it should take so long.  All the UI elements are on the screen.  It only needs to unhighlight the one it was on and highlight the one it is going to.  Unless, maybe it is trying to unhighlight them all before highlighting one?

    But the ListBox has a VirtualizingStackPanel (I think anyway), so why is it so slow?

    The list itself populates FAST, but navigating the elements is almost unusable.

    Anybody can give me a clue?  (not having so many elements is NOT an option)


    • Edited by Mark Tiede Thursday, July 2, 2015 3:24 PM
    Thursday, July 2, 2015 3:24 PM

All replies

  • Are you perhaps not using a datatemplate?

    If you don't have like:

        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Something}"/>
    	</DataTemplate>
        </ListBox.ItemTemplate>

    That used to kill performance.

    I can't actually recall binding such a large itemssource though.

    I'm assuming here you don't actually add ListBoxItems in code. Also bad.


    Hope that helps.

    Technet articles: WPF: Change Tracking; All my Technet Articles

    Thursday, July 2, 2015 3:50 PM
    Moderator
  • Actually, I tried with and without datatemplate. Didn't make any difference.

    One thing that DOES make a difference, is not specifying a HEIGHT.  I think if you don't do that, the first time it tries to load the control, it doesn't virtualize.  So I DO have a height specified.  So it loads almost instantaneously.

    The problem is NAVIGATING that list with the arrow keys.

    The ListBox is using the ItemsSource binding.  Again, loading isn't the problem.

    Thursday, July 2, 2015 3:58 PM
  • I don't know about SilverLight controls but Windows.Forms Listbox can only hold 65535 (I think that's the right number) of entries. That number is also the max size any control can be in width and height and is all the number of items some other controls can display too.

    Although it seems to me it would be simpler to maintain that many items in a List(Of T) and use a search routine to display a limited amount of items in some way such as by alphabetic order within a control so only items beginning with an A are displayed or something. Displaying 65000 items seems unecessary.


    La vida loca


    Thursday, July 2, 2015 4:02 PM
  • As I recall, when I STARTED using BIG lists, I made a test case with 1,000,000 items and it worked fine.  It is all virtualized.  Using the Scroll bars gives EXCELLENT response, even with 1,000,000 items.

    But do an arrow down from the first item to the second, and you wait, BIG TIME.

    ... time passes ...

    Just tested it.  Going from 1st to 2nd item took 10 seconds on a fairly fast machine.

    • Edited by Mark Tiede Thursday, July 2, 2015 4:11 PM
    Thursday, July 2, 2015 4:09 PM
  • Interestingly, a Combobox, which presumably also uses a ListBox for the popup choices can go up and down the list with no delay with the same large list of items.
    Thursday, July 2, 2015 5:17 PM
  • Hi Mark,

    Based on your description, I write test code as below. I create a list that has 1,000,000 entities. I select item in the ListBox with down arrow and up arrow, which has no delay. Do you have add any events or styles for ListBox and Items? Please provide any code snippet that help us to reproduce your problem.

    public MainPage() { InitializeComponent(); List<Test> lst = new List<Test>(); for (int i = 0; i < 1000000; i++) { Test t = new Test(); t.Number = i; lst.Add(t); } lbTest.ItemsSource = lst; lbTest.DisplayMemberPath = "Number"; } }

    public class Test
    {
      public int Number { set; get; }
    }


    Best Regards,
    Weiwei

    Monday, July 6, 2015 5:03 AM
    Moderator
  • Maybe it has to do with the length of the strings in mine. Here is my test code in Remobject's Oxygene language.

    namespace SilverlightApplication73;
    
    interface
    
    uses
      System,
      System.Collections.Generic,
      System.Linq,
      System.Windows,
      System.Windows.Controls,
      System.Windows.Documents,
      System.Windows.Ink,
      System.Windows.Input,
      System.Windows.Media,
      System.Windows.Media.Animation,
      System.Windows.Shapes;
    
    type
      Person = public class
      private
    
      public
         property Name : String; notify;
      end;
    
      MainPage = public partial class(System.Windows.Controls.UserControl)
      private
         method setSelectedPerson(value: Person);
         fSelectedPerson : Person;
      public
         method MyLoaded(sender: Object; e: RoutedEventArgs);
        constructor;
        property MyDict : Dictionary<Guid,Person>; notify;
        property SelectedPerson : Person read fSelectedPerson write setSelectedPerson; notify;
      end;
      
    implementation
    
    constructor MainPage; 
    begin
      InitializeComponent();
      Loaded += MyLoaded;
    end;
    
    method MainPage.MyLoaded(sender: Object; e: RoutedEventArgs);
    begin
    MyDict := new Dictionary<Guid,Person>;
    MyDict.Add( Guid.NewGuid, new Person( Name:='a1' ) );
    MyDict.Add( Guid.NewGuid, new Person( Name:='a2' ) );
    MyDict.Add( Guid.NewGuid, new Person( Name:='a3' ) );
    MyDict.Add( Guid.NewGuid, new Person( Name:='a4' ) );
    MyDict.Add( Guid.NewGuid, new Person( Name:='a5' ) );
    MyDict.Add( Guid.NewGuid, new Person( Name:='1b' ) );
    
    for I : Integer := 1 to 1000000 do begin
       MyDict.Add( Guid.NewGuid, new Person( Name := 'cdefgh' + I.ToString + 'cdefghcdefghcdefghcdefghcdefghcdefghcdefghcdefghcdefghcdefghcdefghcdefghcdefghcdefgh' ) );
    end;
    
    
    DataContext := self;
    end;
    
    method MainPage.setSelectedPerson(value: Person);
    begin
    fSelectedPerson := value;
    end;
    
    end.


    Here is my xaml:

    <?xml version='1.0' encoding='utf-8' ?>
    <UserControl
       
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
    	xmlns:System="clr-namespace:System;assembly=mscorlib"
       
       x:Class="SilverlightApplication73.MainPage"
       
       mc:Ignorable="d"
       d:DesignHeight="300" 
       d:DesignWidth="400"
       >
       <UserControl.Resources>
          <DataTemplate x:Key="PersonItemTemplate2">
             <Grid>
                <TextBlock 
                   Text="{Binding Name}" 
                   VerticalAlignment="Center"
                   HorizontalAlignment="Left" FontFamily="Portable User Interface"
                />
             </Grid>
          </DataTemplate>
    
       </UserControl.Resources>
    
       <StackPanel x:Name="LayoutRoot" Orientation="Vertical">
    
          <ListBox 
             ItemsSource="{Binding MyDict.Values}" 
             ItemTemplate="{StaticResource PersonItemTemplate2}"
             Height="300" 
             HorizontalAlignment="Center"
             VerticalAlignment="Center"
             >
    
          </ListBox>
          
    
    
    
    
       </StackPanel>
    </UserControl>


    I also tried plain List instead of Dictionary.Values.  That didn't make any difference.

    Also, I see you didn't have a binding on SelectedItem.  Maybe that makes a difference.  Actually, I guess in this last test I ran, I don't have a SelectedItem either.

    ... time passes ...

    Interesting, I tried using an Integer and it was just as slow.  Perhaps the difference is using an ItemTemplate.

    ... time passes ...

    Nope, without a template and using an integer, it was just as slow.

    • Edited by mltiede Monday, July 6, 2015 12:47 PM
    Monday, July 6, 2015 12:37 PM
  • I tried to reproduce using your code. It is just as slow. 7 or 8 seconds after each down arrow.

    I'm loading the app, then clicking on an item in the listbox and then doing the down arrow and waiting for the listbox to highlight the line below the one that was clicked on.  Is that what you were doing?  If so, I have no idea why mine would be slower.  This machine is pretty capable.

    Intel Core I7-4770S CPU @3.10GHz 8Gig Ram 64 bit OS x64-based processor Windows 8.1 Pro with Media Center.

    Monday, July 6, 2015 12:59 PM
  • Hi mltiede,


    >>I'm loading the app, then clicking on an item in the listbox and then doing the down arrow and waiting for the listbox to highlight the line below the one that was clicked on.  Is that what you were doing?

    Yes, that is I were doing. And my machine is the same with yours. I set a selectedItem in my code, but there still works fine.

    Is it possible caused by the language that you are using? Please try with C# or other language. I think it should be caused by the large number of list, please try with a list contains about 10 items.


    Best Regards,
    Weiwei


    Tuesday, July 7, 2015 2:03 AM
    Moderator
  • As I said in the previous post, I tried your code (in C#).

    As I said in a previous post, it works fine up to about 10,000 items.  So there is no need to try 10.


    Did YOU try long strings?
    • Edited by mltiede Tuesday, July 7, 2015 12:08 PM
    Tuesday, July 7, 2015 12:05 PM
  • Hi mltiede,

    I have tried long strings but it still works fine in my side. In my opinion, if I add an event such as SelectionChanged or style for ListBox, it will delay with a large number list. But you have tested with no DataTemplate and there has no event in your code. I'm afraid I need some time to think about this problem.

    Best Regards,
    Weiwei

    Wednesday, July 8, 2015 1:31 AM
    Moderator