Hi,
I'm validating the Infragistics UltraGrid (version 6.3) for use in a project. Is there a way to use a bindingsource with complex properties? Example:
class cAddress{ public string Street { get; set; }}
class cResident{ public string Lastname { get; set; } public cAddress Address { get; set; }}
I tried to do the following:ArrayList _Residents = GetResidents() //returns cResident CollectionBindingSource _BindingSource = new BindingSource(_Residents);UltraGrid _UltraGrid = new UltraGrid(); // Would be initialized in designtime for columns etc._UltraGrid.DisplayLayout.Bands[0].Columns[1].Key = "Lastname";_UltraGrid.DisplayLayout.Bands[0].Columns[2].Key = "Address.Street";The property for column 2 does not show up.Any suggestions or help would be great.
Thanks,Iwe
Hi Iwe,
You can't set the Key on a bound column. When you assign the DataSource of the grid, the grid will automatically build the bands and columns based on the data source. In this case, you would get a grid with two columns: LastName and Address. The Address column would not be editable, since it's an object the grid does not know how to edit.
There are a number of ways you can get this to work. The most elegant way (and also the most complicated) would be to implement ITypedList on your cResident class. You could create property descriptors that are aware of the cAddress class and it's properties and return the properties of the Address instance. Basically, what you do is handle GetPropertyDescriptors on ITypedList and remove the property descriptor for Address and replace it with descriptors for Street and any other sub-properties of Address that you want displayed at the root level. As I said, this can be pretty daunting, especially if you are not familiar with ITypedList and PropertyDescriptors. But it's an elegant solution because it will work with any control, not just the grid. The good news is that I wrote a sample of this a while ago and I am attaching it here.
If you want to do this an easier way, then what I would do is use the InitializeLayout event of the grid to hide the Address column. Then add an unbound column to the grid for Street and any other Address properties you want. You would then use the InitializeRow event to populate the Street column with the Address.Street. If the data is editable, you would use BeforeRowUpdate to take the Street value from the grid and update the Address.
Hi Mike, I am implementing ITYpedList but say in the above example, What if I want to add more properties at run time? Is there a way GetItemProperties be called when I modify the Address object? I have a requirement where user can add columns by clicking a button(I know there are other ways to do it, but our DS is complex and Itypedlist will be an elegant solution).
What you have to do is notify the bound controls that a new column was added (or removed or changed). You do that through the IBindingList interface by firing the ListChanged event and passing in ListChangedType.PropertyDescriptorAdded.
Hi, I did the same but for some reason the grid is not reflecting the column added. Please have a look at the attached sample. Please ignore my previous post
I'm confused. I don't see anything in your sample that adds a new property descriptor, nor send a ListChanged notification. In fact, it looks like you are not even implementing IBindingList, but are instead deriving from List<T>.
List<T> doesn't even have a ListChanged event. If you are going to be data binding, I recommend that you use BindingList<T> instead. It's a more robust class with better support for data binding, including the ListChanged event.