Tech Off Thread

6 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Issue when binding WinForm constrols to Generics

Back to Forum: Tech Off
  • User profile image
    dami

    I ran into this issue when I tried to populate a DataGridView with a generic list of my interfaces.

    I have two interfaces and to concrete implementations of them:

    public interface IMyBaseClass
    {
        string Name
        {
            get;
            set;
        }
    }
    
    public abstract class MyBaseClass : IMyBaseClass
    {
    
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
    }
    
    public interface IMyConcreteClass : IMyBaseClass
    {
        string Description
        {
            get;
            set;
        }
    }
    
    public class MyConcreteClass : MyBaseClass, IMyConcreteClass
    {
    
        private string _description;
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }
    }

    If I bind my grid with a List of IMyConcreteClass, the grid just loads the concrete interface members (Description) but it doesn't loads the base interface members (Name). Here is an example of what i'm doing:

    private void Form1_Load(object sender, EventArgs e)
    {
        //load some data ont mylist
        MyConcreteClass classOne = new MyConcreteClass();
        MyConcreteClass classTwo = new MyConcreteClass();
        classOne.Name = "class one";
        classOne.Description = "the class one";
       
        classTwo.Name = "class two";
        classTwo.Description = "the class two";
       
        List myList = new List();
        myList.Add(classOne);
        myList.Add(classTwo);
       
        //add respective columns
        DataGridViewTextBoxColumn column1 = new DataGridViewTextBoxColumn();
        DataGridViewTextBoxColumn column2 = new DataGridViewTextBoxColumn();
       
        column1.DataPropertyName = "Name";
        column1.Name = "The name";
       
        column2.DataPropertyName = "Description";
        column2.Name = "The description";
       
        
        someGrid.Columns.Add(column1);
        someGrid.Columns.Add(column2);
       
        //bind
        BindingSource bs = new BindingSource();
        someGrid.AutoGenerateColumns = false;
        someGrid.DataSource = bs;
        bs.DataSource = myList;
    }

    At the end i just got this on the screen:

    Generic Forum Image 

    Some one knows why is this happening? Sad

  • User profile image
    dami

    Here is the code. [DOWNLOAD]



    Actually it works perfect if I replece the List<IMyConcreteClass> with a List<MyConcreteClass> Perplexed

  • User profile image
    wacko

    dami said:
    Here is the code. [DOWNLOAD]



    Actually it works perfect if I replece the List<IMyConcreteClass> with a List<MyConcreteClass> Perplexed
    The issue here is caused by the fact that the item your putting into the List does not have a get or set for name your IMyBaseClass does, so this does not work out well.  How you got it to work correctly was because you passed in an item that had both a get and set for both string items.

  • User profile image
    dami

    wacko said:
    dami said:
    *snip*
    The issue here is caused by the fact that the item your putting into the List does not have a get or set for name your IMyBaseClass does, so this does not work out well.  How you got it to work correctly was because you passed in an item that had both a get and set for both string items.
    You mean I should override the propertys on the concrete interface?

    But the MyConcreteClass inherits the name property from MyBaseClass, the same way as IMyConcreteClass does from IMyBaseClass... does interface inheritance work like this or i'm wrong? :-/

    thanks for your reply!

  • User profile image
    wacko

    dami said:
    wacko said:
    *snip*
    You mean I should override the propertys on the concrete interface?

    But the MyConcreteClass inherits the name property from MyBaseClass, the same way as IMyConcreteClass does from IMyBaseClass... does interface inheritance work like this or i'm wrong? :-/

    thanks for your reply!
    The issue is your List cannot take something of two types, and with the way you have this setup, Your list is only dealing with one or the other type. So in your case you pass in IMyConcreteClass to your list well IMyConcreteClass does not have an impl of Name so when you pass those objects around its not going to display the name... if you passed in MyBaseClass to the list you will just get the name and not the description why because MyBaseClass does not provide an impl for description it knows nothing about it. So when you pass in MyConcreteClass and it works its because it provides an impl for both name and description.

    This is really a flaw in your design, I do not see a reason why you have all these interfaces and abstract classes. I think that MyConcreteClass should just impl both interfaces and you would be find and then just pass MyConcreteClass as the list type. Or have the Abstract class impl both interfaces and then have MyConcreteClass inherit from that and then pass in MyBaseClass to the list.

  • User profile image
    dami

    wacko said:
    dami said:
    *snip*
    The issue is your List cannot take something of two types, and with the way you have this setup, Your list is only dealing with one or the other type. So in your case you pass in IMyConcreteClass to your list well IMyConcreteClass does not have an impl of Name so when you pass those objects around its not going to display the name... if you passed in MyBaseClass to the list you will just get the name and not the description why because MyBaseClass does not provide an impl for description it knows nothing about it. So when you pass in MyConcreteClass and it works its because it provides an impl for both name and description.

    This is really a flaw in your design, I do not see a reason why you have all these interfaces and abstract classes. I think that MyConcreteClass should just impl both interfaces and you would be find and then just pass MyConcreteClass as the list type. Or have the Abstract class impl both interfaces and then have MyConcreteClass inherit from that and then pass in MyBaseClass to the list.

    Well i still don't get it. I mean, to me, i'm not passing "something of two types" but just one type IMyBaseClass extended.
    Anyways if I debug the code intelisense shows both properties. I could use the name property programmatically with an instance passed through the IMyConcreteClass with out problems.

    But well, it doesn't make sense to keep pushing with this, it is not working, so without a doubt you are right wacko.

    The reason why i have all this interfaces, is because my app is separated into layers that doesn't know anything about each other. To pass data between them i'm trying to use the "Interface-Based Programming" approach where the layers only share a bunch of interfaces in common.

    Any sugestion would be accepted Tongue Out

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.