Have been up all night trying to figure this one out. I am using an Infragistics.Win.UltraWinGrid.UltraGrid. The DataSource for the grid is a BindingSource that uses a custom data structure. Binding and property updates are working fine. Grid is readonly.I want to change the color (toggle) of a row if the underlying value changes. Here is a very simplified snippet of my original code using the recommended InitializeRow event (note, for simplification I am just coloring the whole row for the example, whereas actually I am coloring a cell in my application):private void ugWatchlist_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs e){ if (!e.ReInitialize) return; Infragistics.Win.Appearance app1 = new Infragistics.Win.Appearance(); app1.BackColor = Color.Green; Infragistics.Win.Appearance app2 = new Infragistics.Win.Appearance(); app2.BackColor = Color.Red; if (e.Row.Appearance.BackColor.Name != Color.Green.Name) e.Row.Appearance = app1; else e.Row.Appearance = app2;}However, the color change works only once (and rows turn red on the firs t update and stay that way). According to the code, the color should toggle on each update. I can confirm in the debugger that the BackColor property is indeed changed but not reflected by the UltraGrid.Am I missing something here? I have gone through all the samples and examples and couldn't find a solution to this problem. Please help.
Hi,
I suggest you try with a different version of NetAdvantage and see if the error is still happening. If the issue is not resolved then submit a case to developer support.
Magued
Thanks for all the suggestions. I figured out the problem some days back and just posting the update here. I fixed the issue by firing a timer on each update and resetting the value when the timer gets triggered.
However, now I have to "flash" the cell based on "how" the value changed, i.e. if the value is numeric and it decreased I have to flash it with red, otherwise green. Any suggestions how to get the "previous" value in a cell just before initializeRow is fired?
Hi Al,
This seemed like such a fun and useful idea that I whipped up a quick sample.
I have attached my sample here. All you have to do is instantiate an instance of the GridCellColorizer class and pass in your grid. Then, when you want to color a cell temporarily, you call the AddCell method on the GridCellColorizer and pass in the cell, the color, and the time in milliseconds. The GridCellColorizer takes care of the rest.
You didn't answer my question about whether you wanted to do this on cells or rows, so I went with cells. Rows might be a bit trickier as you would have to apply the appearance to each cell within row.
I chose to use a DrawFilter, instead of setting the Appearance on the cell for a number of reasons. First off, this will be a lot more efficient, since cells that are scrolled out of view can be ignored. Second, I decided to use a sort've fade-out effect by drawing over the cell with a semi-transparent color which would have been impossible using an Appearance.
hey Mike!! so sorry didn't see this email. i need email training apparently. i'm going to try this out today.
Let me know how it goes. :)
i don't think i've ever used the grid to this kind of depth. pretty wild. took me 10 minutes to figure out what the cell colorizer/timer was doing.
i do agree about the cell (actually what i wanted) and the draw filter. very smooth. but what about if the underlying data that's generated (instead of a button in this case) every second or even faster. how does that work? i.e. message pump from windows to grid gets cue'd up? how would that work in this case without having lag?
ok. so i took your app and added a couple of lines of code to demonstrate the volume of it "ticks". literally doing the same thing as your button is doing it but a thousand times faster. "simulating" high volume of events.
create this at the Form1 class level
Timer t1Publisher = new Timer();
//this in constructor
t1Publisher.Tick += t1Publisher_Tick; t1Publisher.Interval = 50; t1Publisher.Enabled = true;
//this is the code for the publisher_tick event
void t1Publisher_Tick(object sender, EventArgs e) { int rowIndex = DummyDataCreator.RandomInt(0, this.ultraGrid1.Rows.Count - 1); int columnIndex = DummyDataCreator.RandomInt(0, this.ultraGrid1.DisplayLayout.Bands[0].Columns.Count - 1); UltraGridCell cell = this.ultraGrid1.Rows[rowIndex].Cells[columnIndex]; this.gridCellColorizer.AddCell(cell, Color.Red, 2000); }
i'm actually thinking of wiring up one of our existing apps to this to see how it works.
OK. i thought i was. i'm able to get the notifyprop changed event to fire when i directly set a value for one of the properties . i have to wire up to each property with a shared handler.
thanks for the help
Al Maiz said:well i'm using notifypropertychanged for all the properties in my class and hoped to listen to those. but doesn't appear to be happening when bound to data source.
I'm not sure I follow you there. If you have your own custom class and implement this interface and you are setting properties and the interface notification is not firing, then something is wrong with your interface implementation. No? Unless something in your class is bypassing the property setter or changing the property values without firing the notification. This has nothing to do with the grid or data binding.
Al Maiz said: i tried to capture the gridAftercELL_update event but that wasn't firing for me when the cell was updated from the underlying data source.
Yes, that's correct.
ok. yes i have just the root band. well i'm using notifypropertychanged for all the properties in my class and hoped to listen to those. but doesn't appear to be happening when bound to data source. i tried to capture the gridAftercELL_update event but that wasn't firing for me when the cell was updated from the underlying data source. i guess it only works from modifiing the data directly (by hand/code)
i've turned your gridcellcolorizer into a gridrowcolorizer which appears to work though i'm still testing. It does use the listchanged event which is a bit silly, i need to determine update vs initial load time, etc. if coloring at a cellular level is to involved then i will pass. it's not worth the effort/risk i guess.
thanks
Well, you are going to be limited by what your data source exposes. I think using the ListChanged interface is probably a good idea. The ListChanged notifications pass you an index, which is an index of the row that was changed in the data source. If your grid is filtered or sorted, finding the matching row in the grid might not be simple, though, especially if you are dealing with child rows
The grid's Rows collection has method called GetRowWithListIndex that will help. On the root band, this is straightforward. You can use the index you get from ListChanged to find the correct row. For a child row, you will have to find the parent row by it's ListIndex first, and then find the child row in the child rows collection.
I don't think ListChanged gives you which field was changed, though. So the only way to determine that would be to update whatever is changing the data so that it also sends you some kind of notification with more detailed info.
ideally , i want to pass the cell (RowXCol) that was updated in the datasource to the gridcellcolorizer, so the users see exactly which field just changed.