I have a scenario where I am binding an object to my grid that contains a property that is another object. Then I am adding the second object's properties to the grid as unbound columns. Something like this:
Object1.ID
Object1.Object2
Object1.Name
Object2.State
Object2.City
So, for the above case my grid would have bound columns of ID and Name. It would also have unbound columns of State and City.
When the underlying object (Object1) is changed, the grid automatically becomes aware of this and my cell text us updated with the new value (like if I change the Name property). However, if the Object2 property of Object1 is changed... like changing the value of the "State" property, the grid will not update with the new value. I am thinking this is because I made State an unbound column. That makes sense to me.
My question is what event can I subscribe to in order to know when to refresh my unbound columns? I am using a binding source with my grid, so I thought I could listen for the ListChanged event or something. This did not fire when my property changed though. How does the bound column know to update when I make that change there?
Thanks!
Steve
Hi Steve,
The grid gets notifications of changed fields from the BindingManager and I don't see how the BindingManager could possible recognize either of these changes, unless you are somehow sending it notifications via an interface like IBindingList or INotifyPropertyChanged.
Are you binding the grid to a single instance of Object1 or some kind of list? I suspect you must be using a List<Object1> or BindingList<Object1>. If you are using one of these and your objects fire events when the properties change, then the BindingManager could detect this. If not, then I'm not sure what's going on there.
But it's hard to tell with so little information about the objects and what you are actually binding to.
Hi Mike,
I am using a BindingSource and a List object with the grid. So, I have the following:
In the Design View I am setting the grid's DataSource to the BindingSource. Then in code I set the binding source's data source to a List object of type Object1.
myGrid.DataSource = bindingSource1;
List<Object1> myObject;
bindingSource1.DataSource = myObject;
After setting this up I altered one of the properties of one of the items in the List.
myObject[0].Name = "123";
After doing this, the grid picked up the change immediately. Name is a bound column in the grid.
Now, when I change a property of the sub object, the grid does not see the change because the column is unbound (I think):
myObject[0].Object2.State = "123";
At this point I also changed my List<Object1> to a BindingList<Object1> and tried the same thing. The grid still did not pick up the change, which I expected. However, I then tried to subscribe to the ListChanged event of my BindingList<Object1> object. This still did not work. The ListChanged event did not fire when I changed the State proprety. Neihter of my classes implement INotifyPropertyChanged.
Since the grid is notified of a change to the Name property, I figured there would be a way to see the State property change as well. I just can't find the correct event to listen for. Maybe this won't work though.
Thanks so much Mike! Your example of "new Object2("123")" really cleared it up for me. Also, your solution of using INotifyPropertyChanged is exactly what I need. Currently, I am refreshing the entire grid, but I would rather not do that. Thanks!
Okay, so that all makes sense. When you set the Name property on an Object1, you are actually changing the value of a cell in the grid.
When you set a property on a Object2 which is a property of the Object1, you are not changing the value of the cell and neither the BindingManager nor the grid has any way to detect this.
If you did this, it would work:
myObject[0].Object2 = new Object2("123");
See the difference?
Anyway, you have a couple of options here. The most comprehensive way to handle this would be to implement INotifyPropertyChanged on Object2 and Object1. The Object1 would have to hook into these notificatifcations on it's current Object2 instance and bubble up that notification. So when Object2's state changes, Object1 fires a change notification for it's own Object2 property.
An easier, but less elegant way to deal with this is to just notify the grid that it needs to reload the data. You can do this by calling grid.Rows.Refresh(ReloadData). But, of course, you have to do this any time a sub-object property changes.