I am trying to change the color of a Row based on a value, which works perfectly. Except I need to change the row above this row as well, and this works on the first refresh of the grid, but subsequent refreshes it doesn't work because e.Row.Index is not the index but -1.
This is the code I am using:
Me.grd_Main.Rows(e.Row.Index - 1).Appearance.BackColor = cClosedControllerBlue
Any ideas why it works the first time and not subsequently?
Thanks
M
Hi M,
Is the Index actually -1? Or is the Index 0 and it comes out -1 when you subtract one from it. I can't see any reason why any row in the grid would ever return -1 for it's Index.
That is the crazy part, it is actually -1, I had to put a check in because it was crashing with a -2 once I subtracted 1.
I had to look in the documentation to try and figure out what a -1 meant, of course it doesnt exist. That's how I ended up here.
If I can reproduce it in a simpler sample project, would that be of value in figuring it out?
Thanks for following up on this, I greatly appreciate your help.
I have narrowed it dow with some sample code, it is an OutlookGroupBy issue.
These two lines of code cause the problem to reproduce. I can send you the simple 50 lin project that reproduces it, if that helps.
Me.UltraGrid1.DisplayLayout.Bands(0).SortedColumns.Add("SortValue", False, True)
Thanks again.
If you can duplicate this in a sample, then I recommend submitting the issue to Infragistics Developer Support so they can check it out. Maybe there is some reason why a row would have an Index of -1, but if so, the reason escapes me. Sounds like a bug.
Get Help
Hi All,
This is still happening even more than eight years after it was reported. I modidied class frmExternalSummaries in CSharpSamplesExplorer solution and added an event handler to UltraGrid InitializeRow event. I added one statement in my event handler:
Trace.WriteLine(string.Format("InitializeRow - band: {0}, row: {1}", e.Row.Band.Index, e.Row.Index));
I got the following output:
InitializeRow - band: 0, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 0, row: -1
Is there a workaround to suppress these?
Thanks,Shaolin
Hi Shaolin,
I tried this out and I get the same results. But we were never able to duplicate the issue before. As you can see, my last reply to this thread asked for a sample and then the customer never followed up.
Anyway, there are a number of factors at work here. This sample is loading the grid on-demand and it's calling ExpandAll in the form initialization, so my guess is that these rows are getting initialized before they are actually part of the grid's Rows collection and that's why they don't have a valid index.
This may or may not be a bug, but frankly, the Index of the row is not a very useful thing in most cases, anwyay. Row indices will change when you filter or sort the grid, so it's not something you can generally rely on for anything important.
The obvious workaround would be to simply check for -1 and then bail out of the InitializeRow event. Of course, it depend what you are using the event for and why you need the row index.
Hi Mike,
Thanks for your detailed explanation!
My grid is in virtual mode. I have a data source that is a list. I do sorting and filtering to my data source using work threads. The row of a row in the grid is mapped to the index of the record in my data source. I use the row index to get its data record and set the row level appearances based on the values of some record fields. For performance reasons, I try to stick with my data record instead of UltraGridRow. I always call Refresh(RefreshRow.FireInitializeRow, true) to Rows of my grid when I need to fresh data records in the data source to the grid, so my InitializeRow event handler is eventually called with a correct row index. My consider is the performance and would like to suppress these event calls for all rows with an index of -1. I have tens of thousands records and records in the data source and they are added and removed quite often.
I also noticed that IntinializeRow event was fired before any column data was requested:
CellDataRequested - Band = RootBand; Row = 0; Column = ID; Data = 0; CellDataRequested - Band = RootBand; Row = 0; Column = Col0; Data = 459239609; CellDataRequested - Band = RootBand; Row = 0; Column = Col1; Data = 262; CellDataRequested - Band = RootBand; Row = 1; Column = ID; Data = 1; CellDataRequested - Band = RootBand; Row = 1; Column = Col0; Data = 1431531252; CellDataRequested - Band = RootBand; Row = 1; Column = Col1; Data = 263; CellDataRequested - Band = ChildBand; Row = 0; Column = ChildCol0; Data = 0.73772578441432; CellDataRequested - Band = ChildBand; Row = 0; Column = ChildCol1; Data = 31; CellDataRequested - Band = ChildBand; Row = 1; Column = ChildCol0; Data = 0.229192165298943; CellDataRequested - Band = ChildBand; Row = 1; Column = ChildCol1; Data = 32; CellDataRequested - Band = ChildBand; Row = 2; Column = ChildCol0; Data = 0.927423017065703; CellDataRequested - Band = ChildBand; Row = 2; Column = ChildCol1; Data = 33; CellDataRequested - Band = ChildBand; Row = 3; Column = ChildCol0; Data = 0.914841804613751; CellDataRequested - Band = ChildBand; Row = 3; Column = ChildCol1; Data = 34; CellDataRequested - Band = ChildBand; Row = 4; Column = ChildCol0; Data = 0.0830325270458276; CellDataRequested - Band = ChildBand; Row = 4; Column = ChildCol1; Data = 35;
How do we specify a row appearance efficiently base on data in that row?
I can't think of any reason why the Index of the UltraDataRow would change... unless you inserted or deleted a row. In which case, every row below that row would have it's index modified.
You are correct that sorting the grid only sorts the grid rows and doesn't affect the DataSource.
Yes, I meant to say "get hold of the UltraDataRow". Will the index of a UltraDataRow get changed in its life time? If not, this index will be the index of my record in my data list. My assumption is that the index of UltraGridRow gets changed because of sorting but nothing will affect UltraDataRow's index in its life time. In my applications, UltraGrid sorting is disabled, so the index of a UltraGridRow should eventually be same as UltraDataRow. Could you please correct me if my assumption is wrong?
Thanks so much,Shaolin
This is such a complex scenario and there's so much going on that I am having a hard time figuring out how to assist you with this.
Does the InitializeRow event on the grid fire again at some point after the data has been populated into the data Source? If so, then all you have to do is ignore the InitializeRow when the Index is -1 and when it fire again later, it will work fine.
If not, then there are two ways I think we can approach this. One is for you to try to work around the issue and prevent the InitializeRow from being called before the data is populated. As I recall, you pointed out how to duplicate this behavior using one of our samples, but the problem depends on a number of very specific things happening in order. For example, the problem only occurs when you call ExpandAll on the grid's Rows collection before it has painted the first time. So one potential workaround would be to defer the ExpandAll until after the grid paints. You could easily do this by hooking the Paint event of the grid. The first time it fires, you call ExpandAll and then unhook the event.
If that doesn't help, there may be other ways to work around the issue.
If none of that helps, then I could write this up as a bug for our developers to look into and see if the current behavior is correct or not, and if not, see what we can do about fixing it.
Shaolin said:Is there an easy way for me to get hold of the UltraGridRow by using the UltraGridRow object?
This question doesn't make sense, but I assume you meant to say "get hold of the UltraDataRow". The answer is yes - you can get use the UltraGridRow.ListObject property to get the underlying data object from the data source, which in this case will be an UltraDataRow. I'm not sure how that helps you, though.
The InitializeRow event is fired before any cell data is requested by UltraDataSource. My grid is in virtual mode.
Shaolin said: I also noticed that IntinializeRow event was fired before any column data was requested: InitializeRow - band: 0, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 1, row: -1InitializeRow - band: 0, row: -1 CellDataRequested - Band = RootBand; Row = 0; Column = ID; Data = 0; CellDataRequested - Band = RootBand; Row = 0; Column = Col0; Data = 459239609; CellDataRequested - Band = RootBand; Row = 0; Column = Col1; Data = 262; CellDataRequested - Band = RootBand; Row = 1; Column = ID; Data = 1; CellDataRequested - Band = RootBand; Row = 1; Column = Col0; Data = 1431531252; CellDataRequested - Band = RootBand; Row = 1; Column = Col1; Data = 263; CellDataRequested - Band = ChildBand; Row = 0; Column = ChildCol0; Data = 0.73772578441432; CellDataRequested - Band = ChildBand; Row = 0; Column = ChildCol1; Data = 31; CellDataRequested - Band = ChildBand; Row = 1; Column = ChildCol0; Data = 0.229192165298943; CellDataRequested - Band = ChildBand; Row = 1; Column = ChildCol1; Data = 32; CellDataRequested - Band = ChildBand; Row = 2; Column = ChildCol0; Data = 0.927423017065703; CellDataRequested - Band = ChildBand; Row = 2; Column = ChildCol1; Data = 33; CellDataRequested - Band = ChildBand; Row = 3; Column = ChildCol0; Data = 0.914841804613751; CellDataRequested - Band = ChildBand; Row = 3; Column = ChildCol1; Data = 34; CellDataRequested - Band = ChildBand; Row = 4; Column = ChildCol0; Data = 0.0830325270458276; CellDataRequested - Band = ChildBand; Row = 4; Column = ChildCol1; Data = 35;
I have my data records which are filtered and sorted in my own data source. My UltraGrid is just a window to display a portion of my data. I am trying not to use row.Cells for performance reason.
Each UltraGridRow must be mapped to a UltraDataRow. Even the index of the UltraGridRow is -1 but the corresponding UltraDataRow must have a valid index. Is there an easy way for me to get hold of the UltraGridRow by using the UltraGridRow object? This row index is important to me because it is also the index in my own data source list.
I don't understand your question.
If you want to base the color of the row or cell on a value in a cell of that row, what does the index of the row have to do with it? You don't need a row index to access a value in a cell. You simply use:
e.Row.Cells[columnName].Value