locked
ListView.ScrollIntoView crashes with new virtualisation on RRS feed

  • Question

  • Hi,
    I'm trying to make a ListView (GridView) scoll to it's N-th item programatically, but ScrollIntoView crashes with a NullReferenceException...
    This is the code I'm using, and it's being called from the SelectionChanged event handler of a TreeView that lives next to the ListView in the Window (actually, both the ListView and the TreeView are part of a UserControl):

    1 public void ScrollToItem(int index)     // crashes with NullReferenceException...???  
    2 {  
    3     int N = fileList.Items.Count;  
    4     if (N == 0)  
    5         return;  
    6     if (index < 0)  
    7     {  
    8         fileList.ScrollIntoView(fileList.Items[0]); // scroll to first  
    9     }  
    10     else  
    11     {  
    12         if (index < N)  
    13         {  
    14             fileList.ScrollIntoView(fileList.Items[index]); // scroll to item  
    15         }  
    16         else  
    17         {  
    18             fileList.ScrollIntoView(fileList.Items[N-1]); // scroll to last  
    19         }  
    20     }  
    21 }  
    22  

    I also tried my older version, which used the ItemContainer... stuff:

    1 public void ScrollToItem(int index)  
    2 {  
    3     IList list = (IList)fileList.ItemsSource;  
    4  
    5     int N = list.Count;  
    6     if (N == 0)  
    7         return;  
    8     if (index < 0)  
    9     {  
    10         object iTemp = fileList.ItemContainerGenerator.ContainerFromIndex(0);  
    11         fileList.ScrollIntoView(iTemp); // scroll to first  
    12     }  
    13     else  
    14     {  
    15         if (index < N)  
    16         {  
    17             object iTemp = fileList.ItemContainerGenerator.ContainerFromIndex(index);  
    18             fileList.ScrollIntoView(iTemp); // scroll to item  
    19         }  
    20         else  
    21         {  
    22             object iTemp = fileList.ItemContainerGenerator.ContainerFromIndex(N - 1);  
    23             fileList.ScrollIntoView(iTemp); // scroll to last  
    24         }  
    25     }  
    26 }  
    27  


    but that doesn't do anything because I get an iTemp object that is null...

    The settings for the ListView are as follows:

        <ListView x:Name="fileList" 
                  SelectionMode="Extended" 
                  ItemsSource="{Binding Path=FileListItems}" 
                  ItemContainerStyle="{StaticResource listViewItemContainerStyle}" 
                  IsSynchronizedWithCurrentItem="True" 
                  SelectionChanged="fileList_SelectionChanged" 
                  MouseDown="fileList_MouseDown" 
                  AllowDrop="True" Drop="fileList_Drop" 
                  ContextMenu="{DynamicResource listViewContextMenu}" 
                  Background="#FF333333" BorderThickness="0" SelectedIndex="-1" 
                  GridViewColumnHeader.Click="fileList_ColumnHeaderClick" 
                  VirtualizingStackPanel.IsVirtualizing="True" 
                  VirtualizingStackPanel.VirtualizationMode="Recycling" 
                  AlternationCount="2">  
    ...  
    </ListView> 

    It looks like the Items may not have been generated yet (as iTemp is null), and that that is the reason why the ListView can't scroll to them... (?)
    Also, right before I make the call to ScrollToItem, the FileListItems has changed to a new ObservableCollection.
    Any ideas what might be going on here? And how to resolve this?
    Thanks,

    Koen
    • Edited by KoenT Monday, September 15, 2008 8:44 AM
    • Changed type Marco Zhou Tuesday, September 23, 2008 4:37 AM OP doesn't revert back
    • Changed type KoenT Tuesday, September 23, 2008 11:15 AM did send an example project
    Friday, September 12, 2008 4:04 PM

Answers

  • I just got the reply from WPF team:

    1. The build issue with name is due to a TextBox in the XAML with x:Name="Name" which creates a field of the name "Name" on PropertiesPanelView.

     

    2. There is a bug in VirtualizingStackPanel causing the null reference exception. To work around the issue, you can the following method instead:

            public void ScrollToItem(int index)

            {

                Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,

                    (System.Windows.Threading.DispatcherOperationCallback)delegate(object arg)

                    {

                        int N = fileList.Items.Count;

                        if (N == 0)

                            return null;

                        if (index < 0)

                        {

                            fileList.ScrollIntoView(fileList.Items[0]); // scroll to first

                        }

                        else

                        {

                            if (index < N)

                            {

                                fileList.ScrollIntoView(fileList.Items[index]); // scroll to item

                            }

                            else

                            {

                                fileList.ScrollIntoView(fileList.Items[N - 1]); // scroll to last

                            }

                        }

                        return null;

                    }, null);

            }

     

    Note that the first version of ScrollToItem used ScrollIntoView incorrectly. ScrollIntoView takes data items, not containers. If you had a reference to a container, then you should use BringIntoView directly on the container.

    • Marked as answer by KoenT Thursday, September 25, 2008 8:49 AM
    Thursday, September 25, 2008 5:15 AM

All replies

  • Could you please send your test project to me at v-mazho at microsoft dot com for repro?

    Thanks
    Thursday, September 18, 2008 8:44 AM
  • We are changing the issue type to “Comment” because you have not followed up with the necessary information. If you have more time to look at the issue and provide more information, please feel free to change the issue type back to “Question” by clicking the "Options" link at the top of your post, and selecting "Change Type" menu item from the pop menu. If the issue is resolved, we will appreciate it if you can share the solution so that the answer can be found and used by other community members having similar questions.

     

    Thank you!

    Tuesday, September 23, 2008 4:37 AM
  • Hi Marco,
    I did provide you a project that exhibits the mentioned problem.
    Could you let me know if you received this in good shape?
    Koen

    PS
    I sent it to v-mazho at microsoft dot com as requested.
    Tuesday, September 23, 2008 11:18 AM
  • I just got the reply from WPF team:

    1. The build issue with name is due to a TextBox in the XAML with x:Name="Name" which creates a field of the name "Name" on PropertiesPanelView.

     

    2. There is a bug in VirtualizingStackPanel causing the null reference exception. To work around the issue, you can the following method instead:

            public void ScrollToItem(int index)

            {

                Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,

                    (System.Windows.Threading.DispatcherOperationCallback)delegate(object arg)

                    {

                        int N = fileList.Items.Count;

                        if (N == 0)

                            return null;

                        if (index < 0)

                        {

                            fileList.ScrollIntoView(fileList.Items[0]); // scroll to first

                        }

                        else

                        {

                            if (index < N)

                            {

                                fileList.ScrollIntoView(fileList.Items[index]); // scroll to item

                            }

                            else

                            {

                                fileList.ScrollIntoView(fileList.Items[N - 1]); // scroll to last

                            }

                        }

                        return null;

                    }, null);

            }

     

    Note that the first version of ScrollToItem used ScrollIntoView incorrectly. ScrollIntoView takes data items, not containers. If you had a reference to a container, then you should use BringIntoView directly on the container.

    • Marked as answer by KoenT Thursday, September 25, 2008 8:49 AM
    Thursday, September 25, 2008 5:15 AM