This is a migrated thread and some comments may be shown as answers.

ScrollIndexIntoViewAsync sometimes not calling its Action parameter

6 Answers 248 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Valerie
Top achievements
Rank 1
Valerie asked on 29 Apr 2013, 04:28 PM
We have an application where we want to programatically scroll and select an item in the list. We are using ScrollIndexIntoViewAsync passing in an Action delegate. Sometimes the code doesn't get into the Action method. We know this because we have put in logging both in the method that calls ScrollIndexIntoViewAsync and into the delegate. It gets into the first but not the latter. So the grid scrolls but no item gets selected.

I have tried to reproduce this in a sample app but am not able to. Our application is quite complex, using a Virtual collection and dynamic columns. But I wouldn't think that these should affect whether the callback method is called. Is there something that could explain why the Action delegate does not always get called?

Thank you,
Valerie

6 Answers, 1 is accepted

Sort by
0
Rossen Hristov
Telerik team
answered on 30 Apr 2013, 07:00 AM
Hello,

By design, the scrolling logic will attempt to scroll into view the item a fixed amount of times, i.e. 100 and if it does not succeed it will give up and then the Action method will not be called. But the scrollFailedCallback should be called. This is because of virtualization where we don't know what the height of unrealized rows is so we cannot actually compute the offset of the item that you want to scroll into view. That is why we approximate where this item might be and then we start to try and find it by realizing more and more rows until we manage to actually find the row. If we can't find it after 100 attempts we give up. When this happens and we give up we will not call the scrollFinishedCallback but the scrollFailedCallback. You can try to call the ScrollIntoViewAsync method from the scrollFailedCallback if you want to.

Since we can't reproduce the issue locally, here are some things that you can try:

1. Disable row virtualization by setting EnableRowVirtualization="False".
2. Switch to our brand new virtualization mechanism called Flat mode by setting RadGridView.GroupRenderMode="Flat".
3. Call ScrollIntoView or ScrollIntoViewAsync once more from inside the scrollFailedCallback. Beware of endless loops.
4. Define a fixed row height in order to help us calculate the offset to which we need to scroll by setting RadGridView.RowHeight to something.
5. Since you are working with a virtual collection, you might want to try the ScrollIndexIntoView version of the method, since items can be null in a virtual collection and if they are null we don't really know where we should scroll.

If we can get something that we can debug, we will have more information regarding this problem.

I hope this helps.

Regards,
Rossen Hristov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Valerie
Top achievements
Rank 1
answered on 30 Apr 2013, 04:30 PM
Thank you for your reply. I overlooked the scrollFailedCallback. I just added it to my code and sure enough that is where it is landing when it doesn't land in the scrollFinishedCallback. Now my question is how can I access information about why it failed. Was there possibly an exception thrown or some other issue? How can I determine that so that I can look into correcting it.

I am using ScrollIndexIntoViewAsync, not ScrollIntoViewAsync. I wasn't sure if you were saying that the former can also 'suffer' from not knowing the row height, but I did try hardcoding that and it did not help. Below I provide answers to your itemized list (in square brackets and italics)

1. Disable row virtualization by setting EnableRowVirtualization="False". [I can't set this to false since we are using virtualization]
2. Switch to Flat mode. [We are using Flat already]
3. Call ScrollIntoView or ScrollIntoViewAsync once more from inside the scrollFailedCallback. . [I tried this but it failed again]
4. Define a fixed row height .[Did this, but it did not help]
5. Since you are working with a virtual collection, you might want to try the ScrollIndexIntoView version of the method, since items can be null in a virtual collection and if they are null we don't really know where we should scroll. [This is what I have been using all along].

I should mention that even when it lands in the scrollFailedCallback that the grid did appear to scroll. I do see that document realized in the grid. It's just that it is not being selected because it isn't landing in the scrollFinishedCallback where I set it to be selected.

So again, my question is whether there is a way to find out why it is landing in the scrolllFailedCallback. Do I have access to something that tells me why it failed.
Thanks so much, Valerie 


0
Rossen Hristov
Telerik team
answered on 01 May 2013, 07:27 AM
Hi,

I will try to briefly explain how the code works.

Unfortunately, there is no way to determine why it landed in the scrollFailedCallback. After each attempt to scroll an item into view, there is code that checks whether the item is in the view port. If it is not in the view port a new attempt is made until the maximum amount of attempts (100) has been reached. If the item is still not in the view port after 100 attempts then we simply call the scrollFailedCallback. No exceptions occur -- if they did you would crash with them, i.e. they would be un-handled -- we don't handle them.

The interesting thing here is that you say that the item is in the view port because you can see it on your screen. But apparently our code that checks whether the item is in the view port thinks that it is not. So it is possible that there is some kind of a bug. That is why I will need to reproduce this behavior locally where I can debug it attached to the source code of the grid and see why this happens. Do you think that there is any chance that I can get a sample project that can actually reproduce this behavior. I know that it might be impossible, but I really need to be able to debug something in order to fix it in case there is a problem.

Another possible workaround: If the item is indeed in the view port and you can see it, can't you try setting the RadGridView.SelectedItem from the scrollFailedCallback? There should be no problem with doing that. Just an idea.

But if there is a bug indeed I would really like to fix it, for which purpose I will need to reproduce it locally and debug it to see what is going on behind the scenes. Do you think you can help me with that by preparing a dummy project? 

Kind regards,
Rossen Hristov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Valerie
Top achievements
Rank 1
answered on 07 May 2013, 06:35 PM
Hi Rossen,
Unfortunately I have not been able to reproduce this in a demo project. I have tried and tried but there it works just fine.

Thank you for your suggestion to try to select the item in the scrollFailedCallback. I tried that and it works most of the time.

I am using "GridViewRow row = grid.ItemContainerGenerator.ContainerFromIndex(seekIndex) as GridViewRow;" to get the row. Sometimes the row is null so that's why I say it works most of the time.

Maybe you could supply an overload in a future version where the scrollFailedCallback delegate takes a string which could contain an error message. But I understand that you think this message might not be useful if all it says is that it couldn't scroll the item into the view port. Maybe it could include other info that would help identify the problem.

Anyway, I hope maybe someday I can recreate this in a test program.
Valerie
0
Rossen Hristov
Telerik team
answered on 08 May 2013, 07:19 AM
Hello,

The ContainerFromIndex method might return null if the index you are looking for was never realized, i.e. no physical row was created for the given index. This might happen when virtualization is turned on. If you try to get the row for an index which is not on the screen you might receive null because there is no such row in the virtualizing panel.

Also, last week we've made some fixes for the Flat mode which are related to the ContainerFromIndex method. It is possible that if you upgrade to our Latest Internal Build which will be released next Monday you might get different results from the ContainerFromIndex method. I however cannot be sure that this will be the case, since I don't know what the original problem in your project was.

Anyway, if you somehow manage to reproduce this on a steady basis, I would be more than happy to debug it in order to identify what is causing this weird behavior. To tell you the truth, row virtualization is a really tricky algorithm and we are constantly polishing corner cases like the one that you have described.

All the best,
Rossen Hristov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Igor
Top achievements
Rank 1
answered on 21 Oct 2013, 05:00 PM

I have exactly the same problem and after a day of try I resolved changing the ScrollMode from:

ScrollMode="RealTime"


to

ScrollMode="Deferred"


and then the ScrollIntoViewAsync works perfect.

 

Tags
GridView
Asked by
Valerie
Top achievements
Rank 1
Answers by
Rossen Hristov
Telerik team
Valerie
Top achievements
Rank 1
Igor
Top achievements
Rank 1
Share this question
or