OK Folks ... lots of power in the infragistics grid, but I need some help on what "should" be an easy problem. I need the REAL index of the row in the list. This index sits independent of any column sort or row pin. There must be a row property that is storing this index location as I can pin a row, its index changes to 0, I then unpin it and it returns to its original location. I have tried different combinations of the following:
Index
ListIndex
VisibleIndex
But NONE of these 3 properties is actually referencing the real row index for display. So where would I find that row property?
Thanks for any feedback you may have!
Hello,
When you unpin a row, UltraGrid finds the position of the unpinned row, in order to placed it on the correct position in the visible rows collection. So if you pin a row, then re-sort or re-filter some column and unpin the row, UltraGrid placed the unpinned row in the correct position.
So if the Index, ListIndex, VisibleIndex properties doesn’t works for you:
Index The index of this row in its parent collection
ListIndex Returns the index corresponding to this row from the IList that the control is bound to. Return value of -1 indicates that a row has been deleted or doesn't exist anymore.
VisibleIndex Returns the index of this row in its parent collection, relative to all other visible rows. Hidden rows are not counted.
You could handle BeforeRowFixedStateChanged event of UltraGrid and to get the index of the row, which fixed property will be changed (use e.Row in this event), in order to get the index of the row before it is pinned. But you should keep in mind that if customer re-sort or re-filter the grid, when a pinned row is unpinned , this row could be placed on a position different of this before it was pinned.
Please let me know if you have any further questions.
Hmmm... I am not being very clear I guess in the row index that I am looking for, so I will explain why each of the index listed and why BeforeRowFixedStateChanged is such a bad idea. First, I will be more clear as to the problem I am solving. I pull 100 items from the database. Users can "pin/unpin", sort, and filter those rows. These actions ARE NOT saved in the database, so the rows must keep their original display order values. Now the users can also reorder the rows to a specific order. Now the new re-ordered list display order IS saved in the database. Clearly the grid has a property (maybe it is not exposed) that is maintaining its original position but it is not one of the index that you have referenced.
Index - this is the index being displayed - useless for what I am needing when it is pinned/sorted/filtered
ListIndex - this is the original order pulled from the database and does not change even when the Row.Move function is called, so again it is useless if the user moves a row up or down.
VisibleIndex - this is the index in the collection - useless for storing in the database when it is pinned/sorted/filtered
BeforeRowFixedStateChanged- big whoop... not helpful except for pinning, and even then, not very helpful since I need to deal with sorted and filtered conditions
In summary... sorry for being so vague before, but now that I "think" I have explained the problem specifically, I am really hoping that the index property I am looking for is exposed for me to reference. If not, then why not? I can only shake my head in disbelief to think I would have to write my own synchronized array to manage what is clearly already managed by the grid.
But since you are a infragistics staffer - I am hoping you have the magic answers :D
Hi,
I'm still not exactly clear on what you are trying to get here.
It sounds like what you want is that you want to maintain the sorted order of the rows in the grid, but you do NOT want to maintain the order of row that are fixed. Is that right?
If that's the case, the sorting should be no problem. When you sort the grid, the Index property of the rows will return the visible order.
So the only problem is with fixed rows, because fixing a row sets it's index and you don't want to use that index.
To be honest, I'm not sure exactly what the grid does when you fix a row and then unfix that row. It must be internally maintaining some sort of index so that it knows where to put that row when you unfix it. But if you fix a row, then sort the grid, then unfix the row, what happens? Does that row go back to it's original index? Or does it simply get re-sorted into it's new proper position?
If it's just placed into it's proper sort position, then it would be possible for you to determine where that row should go.
If it's placed back to the same index it came from, then storing the Index in the BeforeRowFixedStateChanged would be the way to go - because I am certain that the grid does not expose whatever internal index it is storing.
It seems to me that it might be easier for you to approach this problem from another angle. Why not simply unfix the rows right before you go to save your data, and then re-fix those same rows after the operation is complete?
Mike -
It really depends on what you mean by "sorted", as I allow for column sort which I do NOT want saved as well as row filters which I do NOT want saved. Manual ordering by the user can only be done when the rows are NOT sorted by column or filtered. So my users open the list, and hypothetically, they decide to sort on column A. Not a problem, they just will not be able to drag and drop rows or move rows up or down until they turn the column sort off, which resets the order of the rows. So lets say they do that... they turn sort on, maybe do a filter too, and then find the row they want, pin it to the top and then turn the sort off and clear the filter... all of the rows go back to where they were originally (because the grid IS keeping an internal reference somewhere), but the pinned row is at the top. So then they decide to drag and drop some rows to another location. Those new row locations need to be maintained even though there is a pinned row, but currently the pinned row shows index/visible index as 0 which would not be correct. OK ... I have done the updating through InitializeRow event... but that gets all "goobered up" (technical term) if a row is pinned. So ultimately, I am left with 2 options that I am understanding:
1) no row ordering is allowed if rows are pinned/sorted/filtered
or
2) create my own row index array and synchronize it based on what is going on (which would allow my users to retrieve a list, sort the list, save the list using the sorted row order, and then move rows around for any final tweaking they may want to do).
I was just hoping that there was some way to access the internal row index that is kept separate from the display and the original listindex. I am thinking that the "other" way of thinking about it is that Infragistics did not expose that property and I will have to duplicate the effort or limit my users on what they can do (and we all have the experience in telling users the reason they cannot do things is due to "just because"). Let me know if I have gotten any of my facts wrong... I have much appreciated all of your feedback!
We've all been there. I'm just glad we were able to help you get this resolved. :)
*sigh* there comes a time in every programmer's life when the most seemingly difficult problem is solved by the most obvious answer. You are right, I already have that unbound column tracking display order, I can just do my synchronization by checking the status flags of the grid (e.g. sorted/filtered/pinned) and then do the appropriate update from there. To say that I feel dumb on fixating on finding a grid property would be an understatement. Thank you both for the feedback. Solution found!
I'm still not sure I understand exactly what you want to achieve. Let me take another shot at it, though.
It seems like what you want is for the users to be able to manually move a row to another position explicitly. I assume you have set up Drag and Drop in your grid to allow this. Or maybe you have buttons for moving rows up and down.
If that's the case, then any sorting the user did would completely negate this, of course. So it sounds like what you are saying is that the user has to turn off any sorting in order to do this.
Is that right?
If that's the case, then why don't you simply disallow the moving of rows while there are rows that are pinned, just as you do when there is sorting in play? It seems to me that there's no difference. If you can't allow the user to move rows while sorting is in play, then you can't allow it while pinning is in play, either and for the same reason - it creates ambiguity.
Even if you could determine the "real" index while a row is pinned, there would still be a problem, because the user could pin a row and them move some other unpinned row. The pinned row's position is now ambiguous since the order of the rows changed.
I suppose that maybe what you want is to store the positions whenever the grid is in a good state. So if the user moves a row and then sorts the grid, you want to store the positions that the rows were in before the sort took place and maintain those, regardless of whatever happens afterward. If that's what you want, then I think you could do this using an unbound column in the grid and storing the index of the row at certain key points. You could use BeforeSortChange, for example, to store the index of every row whenever there is no sorting currently in place, but when sorting is about to occur. Similarly, you could update the index in the BeforeRowFixedStateChanged event. In fact, all you really have to do is call a single method from both of these events. This method would check to see if there is any sorted or any fixed rows currently in place and if not, update the unbound column with the current Index of the row.
Hristo -
Thanks for the feedback and insight. After calling the row move, I am then calling the grid.updatedata and then grid.Rows.Refresh(RefreshRow.FireInitializeRow, True) so that all of the rows that are affected get called. In my testing I do not see any changes to the ListIndex. I am using unique row markers, but I do not see how that will help unless I run my own synchronized array, and then I was going to handle the rowID and the row position in the array, but if I am doing something wrong with the ListIndex, let me know. I would really prefer to use what is already in the grid control than to write extra synchronization code.
So it looks like maybe the ListIndex is not changing by the row.move, you may want to check that functionality since it does not change in any of my testing.
"I call the row move using this code"
grid.Rows.Move(aRow, aRow.Index + 1)
grid.UpdateData()
grid.Rows.Refresh(RefreshRow.FireInitializeRow, True)
"I check changes from within the initializerow method using this code"
if e.Row.Cells("DisplayOrder").Value <> e.Row.ListIndex then
{update the displayorder and the database}
end if
but the listindex is not changing on row.move. let me know if you see something different in your code.
BIG Thanks!
Hello ,
The item which you need is ListIndex, it always will returns you the index from the collection. When you use Move() method for a row, first you should commit the changes onto the database and then to get ListIndex again (after Move() and before committing the changes ListIndes is still the same). So I think that your issues is caused by the fact that you get ListIndex before committing the changes onto your database. However I think that you will avoid a lot of efforts if you have an identifier column in your database, and you will be able to identify uniquely each row by its identifier (id). More about identifier you could find on the following links:
http://msdn.microsoft.com/en-us/library/ms175874.aspx
http://msdn.microsoft.com/en-us/library/aa260656%28v=sql.80%29.aspx