none
[Datagrid] ScrollIntoView not working with ObservableCollection itemssource?

    Question

  • Hey everyone, I struggled to get this working in SL2 and now that I've upgraded to SL3 I was faced with issues using the scrollintoview function for the Datagrid.

    At first, based on some examples, I created my itemssource to be an ObservableCollection of my data structure.  At a given point in time I wanted to scroll down to a specific item in the grid but I kept getting an argument out of range exception The dispatcher work around fixed this for me in SL2, but come SL3 my issue appeared again.

    After looking at more examples I switched up my itemssource use a List of my data structure instead of an ObservableCollection [since the error involved an "index"], and - BAM - it seems to work now.

    My question is, though, SHOULD scrollintoview be working with an ObservableCollection itemssource?  Or does it work, but I am doing something incorrect?

     

    Thank you! 

    Monday, November 30, 2009 4:42 PM

Answers

  • Hi,

       Are you using Ria services ?

      If that is the case you can get information from DomainContext.IsLoading.

      If you are using domaindatasource, this control even has an event called LoadedEvent.

      Once you know if the load operation has completed then you can set the datagird's itemsSource.

      After set the ItemsSource you can call Dispatcher.BeginInvoke to enable the Button.

    Best Regards

     

    Thursday, December 03, 2009 10:20 PM

All replies

  • Actually scratch that... I'm still getting the same error even with List. 

    Any ideas?

    Monday, November 30, 2009 5:20 PM
  • When you call ScrollIntoView, are all the items showing, and everything is populated in the DataGrid?  Do you have the callstack of the exception?  Thanks

    Tuesday, December 01, 2009 9:03 PM
  • No, the items are not yet showing and I imagine that part of the issue [event though I've setup the datasource, the datagrid does not yet contain the data.

     Here is what I'm doing essentially: 

    // _TabData is an ObservableCollection<mySingleRowObject>
    // Set the itemsource
    __TabDataGrid.ItemsSource = _TabData;
    
    // Find the index of the item in the collection that I 
    // want to select. Essentially this goes through and compares
    // a timestamp to determine which item in the datasource I wish
    // to "scroll to" 
    __TabDataGrid.SelectedIndex = FindIndexToSelect();
    // I was told to update the layout to try and fix my problem
    __TabDataGrid.UpdateLayout();
    
    // I was told to try and dispatch the scrollto to fix
    // my problem
    __TabDataGrid.Dispatcher.BeginInvoke(
      delegate
      {
        // I was told that the grid must have focus in 
        // SL3 for the scroll to happen.
        __TabDataGrid.Focus();
    
        // Exception occurs here
        __TabDataGrid.ScrollIntoView(__TabDataGrid.SelectedItem,
                                     __TabDataGrid.Columns[0]);
      });
    
     

     This is the call stack I get for the exception:

     

    >	System.Windows.Data!System.Windows.Data.PagedCollectionView.GetItemAt(int index = -1) + 0x8f bytes	
     	System.Windows.Controls.Data!System.Windows.Controls.DataGridDataConnection.GetDataItem(int index = -1) + 0xfe bytes	
     	System.Windows.Controls.Data!System.Windows.Controls.DataGrid.GenerateRow(int rowIndex = -1, int slot = -1) + 0x52 bytes	
     	System.Windows.Controls.Data!System.Windows.Controls.DataGrid.InsertDisplayedElement(int slot = -1, bool updateSlotInformation = true) + 0xb8 bytes	
     	System.Windows.Controls.Data!System.Windows.Controls.DataGrid.GetExactSlotElementHeight(int slot = -1) + 0xa9 bytes	
     	System.Windows.Controls.Data!System.Windows.Controls.DataGrid.ScrollSlotIntoView(int slot = 9, bool scrolledHorizontally = false) + 0x5bd bytes	
     	System.Windows.Controls.Data!System.Windows.Controls.DataGrid.ScrollSlotIntoView(int columnIndex = 0, int slot = 9, bool forCurrentCellChange = true, bool forceHorizontalScroll = true) + 0x158 bytes	
     	System.Windows.Controls.Data!System.Windows.Controls.DataGrid.ScrollIntoView(object item = {MultiTrend.SingleTabRowData}, System.Windows.Controls.DataGridColumn column = {System.Windows.Controls.DataGridTextColumn}) + 0x2f6 bytes	
    

      

    Thank you for taking the time to look into this for me!

     

    Wednesday, December 02, 2009 12:48 PM
  • If you dont call the ScrollIntoView method, do you ever get to see the datagrid loaded?

    When are you calling the method you posted?

    What happens if you call it in another event (ie a button click) after you are seeing the data?

    Wednesday, December 02, 2009 3:07 PM
  • Instead of calling ScrollIntoView right after setting the ItemsSource, attach to the DataGrid's (or the Page's) Loaded event and BeginInvoke the call to ScrollIntoView in your handler.  If that doesn't work, try to add another BeginInvoke so that you BeginInvoke all call that then BeginInvokes the call to ScrollIntoView?  The most I've had to do is 3 in a row before everything is actually loaded.  This isn't ideal at all, but with the Loaded event not working properly, there isn't much of a choice

    Wednesday, December 02, 2009 4:00 PM
  • If I don't call the method then the grid will eventually become loaded correctly.  A server is hit for some data samples, and when those samples are returned the collection is populated and then the code that I posted is ran.  If I setup a button to run the scroll functionality and hit that button when I can visually see the grid is loaded, then the scroll works fine.

    I imagine the problem is that I am trying to scroll before the grid is fully loaded, I just can't figure out exactly how to tell when the grid *is* fully loaded.  I tried the Loaded event, but I'm fairly certain that it does not work correctly, and I have tried to use the RowLoaded event to try and guess when the row I want to scroll to has been loaded, however, if the row I want to scroll to is not visible in the grid then it appears to not become "loaded".

    I will try the multiple begin invoke method for the time until the Loaded event is fixed.

    Thank you everyone for your continued help!  I appreciate your time :)

    Wednesday, December 02, 2009 6:41 PM
  • Hi,

       Are you using Ria services ?

      If that is the case you can get information from DomainContext.IsLoading.

      If you are using domaindatasource, this control even has an event called LoadedEvent.

      Once you know if the load operation has completed then you can set the datagird's itemsSource.

      After set the ItemsSource you can call Dispatcher.BeginInvoke to enable the Button.

    Best Regards

     

    Thursday, December 03, 2009 10:20 PM
  • Hi,

       Are you using Ria services ?

      If that is the case you can get information from DomainContext.IsLoading.

      If you are using domaindatasource, this control even has an event called LoadedEvent.

      Once you know if the load operation has completed then you can set the datagird's itemsSource.

      After set the ItemsSource you can call Dispatcher.BeginInvoke to enable the Button.

    Best Regards



    I am not using RIA; I'm embarrased to say that this is the first that I've heard of that library.  The data I am retrieving to be displayed in my grid is via async WebClient requests made to services we host on our server.

    After first reading this post I figured RIA was a SL4 beta only thing, but a quick search showed me this is not the case.  I will look into it to see if it could be useful for my situation!

    Thanks! 

    Friday, December 04, 2009 10:25 AM