views:

37

answers:

2

How should I bind my collection of T objects which implements an interface and adds more properties to a DataGrid? Here is an example:

// interface
public interface IPerson{
[DisplayName(@"FullName")]
string Name{ get; }
}

// implementation
public class Employee : IPerson{
[DisplayName(@"Net Salary")]
public int Salary { 
    get { return 1000; }
}

public string Name{
    get { return "Foo"; }
}

// collection
SortableBindingList<IPerson> MyList { get; set }
...
...
MyList.Add(new Employee());
...
dataGridView.DataSource = MyList;

When I do this, it only binds Name but not Salary.

Is there any way to bind to both the properties (Name and Salary in this case)? Thanks.

A: 

Name is in your interface, but Salary isn't. Add Salary to your interface and it should work fine.

If you don't want to change your interface, use SortableBindingList<Employee> MyList instead of SortableBindingList<IPerson> MyList

Robert Harvey
What if, for some reasons, I'm not allowed to do that?
chown
Yes, I can change the datasource definition. I've the source code (it is just a pet project that I'm working on). The only restriction is that I cannot add Salary property to the base interface.
chown
+1  A: 

It is because of Salary is not in your IPerson interface definition.

You should either add Salary to your IPerson interface and implement that in your Employee class or change your MyList property definition as below;

SortableBindingList<Employee> MyList { get; set } 

Edit After Comments

You can achive your goal by implementing ITypedList. It is not a trivial task. So i would not recommend you to do that if you do not have to.

You may inherit from SortableBindingList<IPerson> and implement ITypedList. You should also create a custom PropertyDescriptor to get it work.

Here is a good article about the subject Virtual Properties that i have just found. (The article is the first result of searching the ITypedList and PropertyDescriptor keywords together by the time being).

Hope this help.

orka
Nope. I cannot do this either. Because I've also got another class Student that implements Person. And depending on a setting, I can either create a list of Employee or Student. That's the reason for using an interface rather than anything else.
chown
Has student class a salary property?
orka
No. It doesn't.
chown
It looks like you are doing something logically wrong but you can achive your goal by a custom binding solution such as implementing ITypedList or IBindingList. I suggest you to check the requirements and your solution again rather than going to the custom binding way.
orka
I'm looking into ITypedList but even with that I cannot get it right. I belive that ITypedList is the way to do it but no luck with it.
chown