Hi,
I use a wingrid which auto refreshes every 5 seconds.The problem that I face is when the user scrolls down the grid, suddenly the grid refreshes and moves back up to the top.I want the grid to stay in the same scroll area after refreshing.I set the the first row as active row after every refresh.
So how to save the current scroll position and load the same back after refresh?Or can anyone suggest a better solution?
Thanks,
Abja
I used this in the past after refreshing...
grid.Rows.ScrollCardIntoView(grid.ActiveRow);
This takes a row that it scrolls into view you'll need to know where you are in the grid as your setting you active row to the first...
You are going to lose more than just the scroll position. If you are resetting your data source, you will lose all state information in the grid. This includes row height, expanded state, column widths, selected rows, etc.
So you are probably better off not resetting the data source if you can avoid it.
The above line of code will only work in CardView, so that's probably not the right way to do. What you want is the FirstRow property on the ActiveRowScrollRegion. You can set this to the row you want at the top.
However, you can't store the row you had before the reset and then use the same row to restore the position, because the rows will all be destroyed and a whole new set of rows created. So the row you store won't be in the grid any more after the reset takes place. You will have to store some kind of key information about the row and then find that row again.
Hi Mike,
Thanks for the reply.I managed to reload the state information by using the displaylayout.save() and load functions.But what I want to set is the active scroll region same as the old.I tried as you said.But the grid's FirstRow property on the ActiveRowScrollRegion is always the filter row as I have a filter row on the top.The active scroll region actually changes from the second row only. What I have to set is the second row.I am able to get the second row from the visible rows collection and i can keep the ID or some other value for finding the same row after refresh.
But I dont know which property I need to set ? Or plz advice me how to handle this?
Thanks in advanz
Hi Abja,
Hm. Maybe you could use the ScrollRowIntoView method. This is also on the ActiveRowScrollRegion. I think this method might have an overload that allows you to specify that you want the row scrolled to the top, but I could be wrong.
Also note that the DisplayLayout does not include any row or cell settings. So it will take care of the column width (since columns are on the band and thus part of the data structure), but it will not include the expanded or selected state of the rows.
Hi, I store primary keys of the First row before DataSource is updated and then loop through the rows after datasource is updated to check if for the row with those PK's.
I store this row in a selfmade FirstRow property and in the paint event, if the datasource has been updated (saves this with a boolean), I set the DisplayLayout.RowScrollRegions[0].FirstRow = this.FirstRow.
This works great as long as I don't do a GroupBy with the UltraGrid.
When the DisplayLayout.RowScrollRegions[0].FirstRow.IsGroupByRow == true. I Store the Row.Description (since groupbyrows don't have Primary Keys) and search for it after DataSource is updated. Strangely enough, The correct row is saved in my FirstRow property! but then when I do:
DisplayLayout.RowScrollRegions[0].FirstRow = this.FirstRow
eg:
this.FirstRow.Description = 'Plan Department: BE (16 items)' -> this is the first row before I refreshed
DisplayLayout.RowScrollRegions[0].FirstRow = 'Plan Department (5 items)' - this is the first row of the whole grid
The DisplayLayout.RowScrollRegions[0].FirstRow is still the top first row of the grid(not of the rowscrollregion). So it always scrolls to the top of the grid instead of the location it was before the refresh.
Do you have any idea where it could go wrong? And I was wondering why RowScrollRegions is a collection since DisplayLayout.RowScrollRegions[>0] is always IndexOutOfRange.
Any help would be greatly appreciated!
You kinda lost me about half way through your post. I was with you up until this:
AndyCaignie said: When the DisplayLayout.RowScrollRegions[0].FirstRow.IsGroupByRow == true. I Store the Row.Description (since groupbyrows don't have Primary Keys) and search for it after DataSource is updated. Strangely enough, The correct row is saved in my FirstRow property! but then when I do: DisplayLayout.RowScrollRegions[0].FirstRow = this.FirstRow
I'm not sure that using the description of the GroupbyRow makes sense here, since the description may change if the number of child rows within the group changes.
You would probably be better off using a combination of the Column and the Value of the GroupByRow. that would be a more generic solution.
But I'm not entirely sure I understand exactly what the problem is as you describe it.
AndyCaignie said:And I was wondering why RowScrollRegions is a collection since DisplayLayout.RowScrollRegions[>0] is always IndexOutOfRange.
To create a new RowScrollRegion, you can call the Split method on an existing scrollregion in code. Or, you can drag the little thumb which is above the vertical scrollbar. This thumb will not be displayed if MaxRowScrollRegions is 1, though.
The only thing I want in fact is to have the same screen after the users click refresh (or an automatic refresh). Refresh = reload the datasource.
If a groupbyrow was the first displayed row, than that groupbyrow should be the first row to display after the refresh. If it's a datarow, then it should be that datarow. I don't think I'm the only one requiring that behaviour. Nothing more frustrating for the user to have to scroll back to where he was before the refresh, after each refresh.
For the groupbyrow, I use the description but I split the string to not include the '( 3 items)' when comparing after the refresh, because indeed, after a refresh it could be different. But I can try working with a Column and Value combination too, that's not the issue I think.
I just need to know how to keep the same row (groupedby or not) on the visible top after a refresh than it was before the refresh. How would you implement that?
I'm not sure it's a good idea to call BeginInvoke on the delegate. You should probably be calling BeginInvoke on the grid or the form and passing in the delegate.
But if that didn't work, then it's most likely a moot point, anyway.
AndyCaignie said: That is something I don't understand. It would be something like this: int i = 0; int j = 5; i = j; and when you set a Watch on i it would still be 0 instead of 5, this is what happens with the DisplayLayout.RowScrollRegions[0].FirstRow property. It's not logical.
That is something I don't understand.
It would be something like this:
int i = 0;
int j = 5;
i = j;
and when you set a Watch on i it would still be 0 instead of 5, this is what happens with the DisplayLayout.RowScrollRegions[0].FirstRow property. It's not logical.
I'm not sure why this is happening. As I said above, my theory is that it's because the grouping has not completed yet or the FirstRow is getting changed again at some point after you said it, but I'm only guessing here, since I can't see the behavior.
Perhaps at this point, you should try to create a small sample project that demonstrates the problem and either post it here or Submit an incident to Infragistics Developer Support so we can check it out.
Ok, I successfuly managed to implement a delegate to a SetFirstRow Method. After the LoadData method I call this method through the delegate.BeginInvoke(null, null). This calls my SetFirstRow method, I checked this. But the FirstRow is still not changed.
I think it's something to do with the fact that you can't set a groupedbyrow as FirstRow or something like that. I have the Correct row stored, I set it:
not set to correct row <- ugvShipmentMovements.DisplayLayout.RowScrollRegions[0].FirstRow = ugvShipmentMovements.FirstRow; -> correct row
AndyCaignie said:I don't know quite yet if it's a time issue. The weird thing is that it works for datarows and not for groupbyrows.
This makes perfect sense as a timing issue. If the grid is not grouped, the rows are there. If it's grouped, the grouping is done asynchronously.
AndyCaignie said:About the BeginInvoke, I don't knwo how to implement this. Isn't that used for assynchronously calls and multithreading? Don't know for sure this is a good idea.
BeginInvoke is usually used to marshal across threads, but you can call it on the same thread. You just create a method that does what you need to do, then create a delegate to that method and call BeginInvoke with that delegate.
Do a search on this forum for BeginInvoke, I'm sure there are some sample code snippets posted.
I don't know quite yet if it's a time issue. The weird thing is that it works for datarows and not for groupbyrows.
I call the LoadData fucntion at several locations on the frmShipmentMovement Form, the refresh button click, the applyfilter method ... each time the data needs to be fresh.
The InitializeLayout Method is called before the LoadData Method when I debug.
About the BeginInvoke, I don't knwo how to implement this. Isn't that used for assynchronously calls and multithreading? Don't know for sure this is a good idea.
Okay, so it's pretty clear to me that this is a timing issue of some kind. You are setting the FirstRow on the grid and it's getting reset by something that happens after the LoadData method is called.
Where is LoadData being called from?
Perhaps it would be better to move the line of code that sets the FirstRow on the RowScollRegion of the grid to some later point, such as in the InitializeLayout event of the grid.
If that's no good, then another option would be to create a separate method that sets the FirstRow and instead of calling the method directly from LoadData, you use a BeginInvoke to call it. That will create a delay that might solve the issue.