Hi Everyone,
I have an UltraGrid with two bands; the first band contains non-editable parent rows, and the second band has an editable column that may have both ordinary and combobox cells. The value list for each combobox cell is different from others, and it depends on the parent row properties. The UltraGrid is bound to a BindingList, and the value lists, where needed, are instantiated as UltraDropDowns that are bound to a BindingList property of the row's ListObject. The displayed properties implement INotifyPropertyChanged interface to notify the grid of changes.
The code follows:
RDSViewParameter parameter = propertyRow.ListObject as RDSViewParameter; if (parameter.ValueList != null) { UltraDropDown dropDown = new UltraDropDown(); dropDown.SetDataBinding(parameter.ValueList, null); propertyRow.Cells[1].Style = Infragistics.Win.UltraWinGrid.ColumnStyle.DropDownList;propertyRow.Cells[1].ValueList = dropDown; dropDown.DropDownWidth = 0; dropDown.DisplayLayout.AutoFitStyle = AutoFitStyle.ExtendLastColumn; dropDown.DisplayLayout.Bands[0].ColHeadersVisible = false; }
Everything appears to work fine, until I want to reorder the parent rows (first band) through reordering of the bound BindingList. The child rows move with parent rows as expected, but the ValueLists don't! As a result, the moved child row cells often have incorrect styles (Default vs DropDownLists) and incorrect value lists. I tried manually updating value lists (without binding them), but I god all sorts of errors. After searching those errors, I found out that I should not tamper with an UltraGrid that is bound to a DataSource, and figured this is not a good practice. My question is how I can correctly move value lists with cells as their parent rows are reordered.
Any help would be appreciated.
Thanks.
Hi,
Re-ordering the bound list will not have any effect on the grid. The grid stores it's own sort order for the row. So what are you doing to the grid in order to get it to reflect the new order of the rows?
Also, what event are you using to set the ValueList on the cell? The best event to use is the InitializeRow event. That way, if any value in the row changes or if the row is re-created for some reason, the code will fire again and re-set the ValueList.
I can't think of any reason why the ValueList on a row would change to the wrong ValueList, unless something in your code is doing that. The only other possible explanation is that the grid is somehow re-using the UltraGridRow object and somehow hooking it up to the wrong row, but I've never seen any situation in which that happens. So it seems like your code is doing something very unusual here.
Hi Mike, Thank you for your response. Following your suggestion, I moved all ValueList binding to the InitializeRow event handler to solve the problem. The reason that I did not originally use that event was that often the ValueList remains unchanged, and I thought re-binding every time a row is initialized is unnecessary.
One thing I learned was that if I use UltraGrid.SuspendLayout() before making changes to data, the InitializeRow event does not always fire when it should. But this is something that only someone obsessed about performance will do!
Regarding your statement saying that "re-ordering the bound list will not have any effect on the grid," well, I have observed otherwise. All I do is reordering the BindingList, and I can see the grid order responds to the changes in the bound list.
Finally, I think the issue that I used to have before, like you said, was from the grid "re-using the UltraGridRow object," since I often observed ValueLists were unchanged after their owner rows were moved to some place else. Thank you again, you helped me not go any crazier!
Mehdi A said:Following your suggestion, I moved all ValueList binding to the InitializeRow event handler to solve the problem. The reason that I did not originally use that event was that often the ValueList remains unchanged, and I thought re-binding every time a row is initialized is unnecessary.
Well, this is not a totally unreasonable concern. Especially if you are creating a new UltraDropDown control for each cell. It would probably be a good idea to get the ValueList from the cell and cast it to an UltraDropDown before you create a new one. If it's null, you go ahead and create the new one. If it's already there, then all you need to do is initialize the existing UltraDropDown with the correct data source. You could go even further and check it's DataSource to see if it's already set to the same object, too.
Mehdi A said:One thing I learned was that if I use UltraGrid.SuspendLayout() before making changes to data, the InitializeRow event does not always fire when it should. But this is something that only someone obsessed about performance will do!
Are you sure it's SuspendLayout that does it? I can't see any way in which SuspendLayout could possible have any effect on the grid. SuspendLayout is a method on Control that determines whether that control positions it's child controls and the grid rows are not child controls so that doesn't make a lot of sense. Maybe there's an optimization in the grid that is using SuspendLayout as a sort've hack. I guess that's possible, but that would be really weird and I took a quick look at the grid code and didn't see any mention of SuspendLayout. There's BeginUpdate, which prevents the grid from painting, and also SuspendRowSyncrhonization, which prevents the grid from responding to some BindingList Notifications.
Mehdi A said:Regarding your statement saying that "re-ordering the bound list will not have any effect on the grid," well, I have observed otherwise. All I do is reordering the BindingList, and I can see the grid order responds to the changes in the bound list.
I suppose it depends on how you are re-ordering the list. IBindingList doesn't have any kind of a sort notification. But I suppose if you removed a row and re-added it into a new position in the table, that might do it.
Mehdi A said:Finally, I think the issue that I used to have before, like you said, was from the grid "re-using the UltraGridRow object," since I often observed ValueLists were unchanged after their owner rows were moved to some place else. Thank you again, you helped me not go any crazier!
Anyway, I'm glad you got it working. :)
BTW... if the ValueList is never going to change after the first time, then you could just check e.ReInitialize in the InitializeRow event and only set up the ValueList when it's false.
Thanks a lot Mike, these are all great suggestions!