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.
Hi Shaolin,
Regarding the Row index of -1, as I said, you can easily get around this by simply checking for -1 and then bailing out of the event. If you want to prevent the event from firing, then maybe the best thing to do would be not to hook the event until after the call to ExpandAll - since that's what's triggering the InitializeRow in this case.
Shaolin said:How do we specify a row appearance efficiently base on data in that row?
The best way to do this is to use the InitialieRow. If you are concerned about the efficiency, then I recommend that you check out the WinGrid Performance Guide. It discusses the best, most efficient way to apply appearances using the InitializeRow event.
Hi Mike,
I am sorry that I have to come back to this question.
Mike Saltzman said:It discusses the best, most efficient way to apply appearances using the InitializeRow event.
How can I use the InitializeRow event with a Row object of -1 index? For example, the background color is set to Red if the value in Price column is negative and Green for a positive value.
I am working with multiple bands now. After a parent row is expanded, the InitializeRow event is fired only once for all child rows with -1 index. There is no way for me to setup a row appearance based on the column values of the row.
Could you please shed some more light on this issue?
Thanks,Shaolin
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
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 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.
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.
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?