Question

I am trying to bind some controls to an object - which is normally a pretty straightforward process. Unfortunately, if the object that I'm binding to inherits from CollectionBase, binding to that classes fields causes the error:

Cannot bind to the property or column Caption on the DataSource. Parameter name: dataMember

Removing the collectionbase inheiritance makes this issue go away, but I need this object to be a collection. It seems as though CollectionBase causes higher level properties to become "unbindable." Is there some property I can override to fix this? Any other ideas?

I found this example online that summarized the issue pretty easily. Unfortunately, I have yet to find an answer in all the places I've seen this example posted.

Code:

[STAThread]
static void Main()
{
    TestCollection obj = new TestCollection();
    using (Form f = new Form())
    using (BindingSource bs = new BindingSource())
    {
        bs.DataSource = typeof(Test);
        f.DataBindings.Add("Text", bs, "Caption");
        bs.DataSource = obj; // breaks

        //List<TestallData = new List<Test>();
        //allData.Add(obj);
        //bs.DataSource = allData;
        f.ShowDialog();
    }
}

class TestCollection : CollectionBase
{
    public string Caption { get { return "Working"; } }
}
Was it helpful?

Solution

CollectionBase provides interfaces for a List of Objects, as such when used as a datasource the binding tries to look inside the list for the individual binding data. When there is no list, you have a problem.

If you want a the caption and you want to use CollectionBase you should have 2 classes involved, not just one.

public class TestObj
{
    public string caption { get { return "yay"; } }
}

public class TestCol : CollectionBase
{
    //methods that implement CollectionBase for the TestObj type
}

with those two you can bind one of two ways.

TestObj obj = new TestObj();
TestCol col = new TestCol();
col.Add(obj);

//bind to obj, OR bind to col.  Both would work with this setup.

http://msdn.microsoft.com/en-us/library/system.collections.collectionbase%28v=vs.90%29.aspx

There is a sample implementation of CollectionBase there.

UPDATE: EDITED FROM COMMENT

There isn't any method that I personally know which allows you to bind to the outer properties of a collection. As a workaround, you can use a 3 class system (yea, I know, more and more complicated).

public class TestHeader
{
    public string Data {get;set;}
}

public class TestCol : CollectionBase
{
    //...
}

public class TestObj
{
    public TestHeader header {get;set;}
    public TestCol col {get;set;}
}

bind the outer fields to TestObj.header and bind the collection fields to TestObj.col. This is a workaround, but as stated I dont actually know a way to directly implement what you seem to want. I wish I did, There are portions of my own code that would benefit from it.

Another Example

You could also do it with two classes, but you would still need to nest the collection itself

public class TestObj
{
    public string data {get;set;}
    public TestCol col {get;set;}
}

In this case, bind single data fields to TestObj, and collection fields to TestObj.col

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top