First just a short thanks to all who have posted here, I have solved many a problem with all the great solutions provided.
Today, I have a grid with hierarchiel data that has child rows. I want the child rows to be the same background as the parent row. I found how to do this initially with the initialize row event. It looks like this and works just fine:
if (e.Row.ParentRow != null) { e.Row.Appearance.BackColor = e.Row.ParentRow.IsAlternate ? e.Row.ParentRow.Band.Override.RowAlternateAppearance.BackColor : e.Row.ParentRow.Band.Override.RowAppearance.BackColor; }
But if I now sort the grid based on a column, the child rows no longer maintain the backcolor. I thought to make a method that implements similar logic (see below). But running it after the sorting operation, it does not work as expected with many children mis-colored from their parent.
private void SetChildRowBackground() { foreach (var row in grid.Rows) if( row.HasChild() ) foreach( UltraGridChildBand child in row.ChildBands) foreach( var childRow in child.Rows) childRow.Appearance.BackColor = row.IsAlternate ? childRow.ParentRow.Band.Override.RowAlternateAppearance.BackColor : childRow.ParentRow.Band.Override.RowAppearance.BackColor; }
Is their a more appropriate approach?
Kent
1000 rows should be no problem.
This is a great solution for my situation. My grid will typically have only about 200 rows and occasionally have maybe around 1000. It would be one strange day to have a view with 20k rows in this view, and I cannot imagine why that might happen. I have added the line to refire the InitializeRow in the AfterSortChange event as you suggested and it appears to be working wonderfully.
Thanks MIke
Hi Kent,
This is an interesting challenge, and you are not the first person I've seen who is trying to keep the child rows in sync with the appearance of the parent row.
Assuming that your grid does not have a tremendous number of rows, I think your original approach (using InitializeRow) is the better one. The only caveat is that InitializeRow doesn't fire for the child rows when you sort the parent rows. But this is easily handled - you can force InitializeRow to fire using the Refresh method on the Rows collection.
grid.Rows.Refresh(RefreshRow.FireInitializeRow, true);
So you could do that inside of the grid's AfterSortChange event.
Having said that, there are a whole bunch of other cases where the order of the parent rows could change that will not automatically trigger an InitializeRow event. So I put together a sample that encapsulates the RowAlternateAppearance and the synchronization into one class that you just hook up to the grid. The class hooks all of the grid events that I could think of that might alter the 'Alternate' state of a parent row and refreshes the grid like AfterSortChange, AfterRowFilterChange, AfterRowsDeleted, etc. It is, of course, possible that I missed some - but one advantage of using this class is that if you find another grid event that you need to hook, you can just update HookGridEvents method to hook/unhook it and that's it.
As I said, the one caveat here is that if you have a tremendous number of rows in the grid, firing InitializeRow for ALL of them every time you add a row or delete a row or filter or sort might start to cause a performance problem. So you might be able to make that more efficient in some cases by only refreshing the rows collections that you know you need (or might need). But frankly, if you have that many rows in the grid, no human user will be able to deal with all of them at once, anyway. :)
WinGrid_Row_Alternate_Appearance_Synchronizer.zip