views:

98

answers:

1

I've recently been using data binding in c#, and while the way I am doing it is straightforward and works, it does not feel like the best way.

For example, I have a manager class, ie UserManager which has the following interface:

class UserManager
{
  public IList<User> Users { get; ...}
  public AddUser(...)
  public RemoveUser(...)
}

So Adduser and RemoveUser should control the list, with the Users collection as an output. I am using this collection in a binding, ie:

listBindingSource.DataSource = userManager.Users;

I am then manipulating the list via the binding, ie

listBindingSource.Add(new User(...))

This works, of course, but I am completely bypassing the UserManager and the AddUser/RemoveUser functions in there! This of course seems very wrong. What is the correct way to use databinding?

UserManager is inside a lib so I do not want to put any binding objects in there, as I feel that should be a gui thing. On the other hand, with binding, my gui has taken complete control over my collection.

+1  A: 

As your code stands now, you can't do what you're after. At some point, the collection has to support the IBindingList interface (which is what the BindingSource object you have on the form does). If you want to make use of your UserManager class to do the manipulations, for practical purposes you'll have to change the internal data store for the Users property to use a BindingList<User> (you should still be able to return it typed as an IList<User> as you have now, just change the actual concrete implementation to BindingList<User>). Doing this will expose the IBindingList interface to the grid and it will detect changes that are made elsewhere, namely in your UserManager class.

This will, however, only cause it to pick up on changes made to the list, not to individual elements contained in the list (in other words, additions and removals will be reflected on the UI, but modifications won't be). In order to accomplish this, you need to implement IPropertyChanged on the User class (assuming it doesn't already).

Adam Robinson
Thank you, this is very good information. I'm a little concerned with having to specify my internal list as a BindingList, as I feel it should not need to know how it is going to be used. But I suppose the alternative would be some intermediate converting layer, which is not really worth it for a small project.
DanDan
`BindingList` is designed to be presentation-agnostic. All it does is provide the necessary infrastructure for detecting changes. No matter WHAT data binding scenario you use, there *has* to be a change-tracking (or, more precisely, *change notification*) system in place in order for changes to the data to be reflected automatically on the GUI. There is nothing "smelly" about using `BindingList<T>`.
Adam Robinson