Привязка к свойству класса, производного от CollectionBase

Я пытаюсь привязать некоторые элементы управления к объекту, что обычно довольно простой процесс. К сожалению, если объект, к которому я привязываюсь, наследуется от CollectionBase, привязка к полям этого класса вызывает ошибку:

Невозможно выполнить привязку к свойству или заголовку столбца в источнике данных. Имя параметра: dataMember

Удаление наследования базы коллекции устраняет эту проблему, но мне нужно, чтобы этот объект был коллекцией. Кажется, что CollectionBase приводит к тому, что свойства более высокого уровня становятся "не привязанными". Есть ли свойство, которое я могу переопределить, чтобы это исправить? Есть другие идеи?

Я нашел этот пример в Интернете, который довольно легко суммировал проблему. К сожалению, мне еще не удалось найти ответ во всех местах, где я видел этот пример.

Код:

[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"; } }
}

1 ответ

Решение

CollectionBase предоставляет интерфейсы для Списка объектов, поэтому при использовании в качестве источника данных привязка пытается найти в списке отдельные данные привязки. Когда нет списка, у вас есть проблема.

Если вы хотите подпись и вы хотите использовать CollectionBase вам нужно задействовать 2 класса, а не один.

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

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

с этими двумя вы можете связать один из двух способов.

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

Существует пример реализации CollectionBase там.

ОБНОВЛЕНИЕ: ИЗДАНО ИЗ КОММЕНТАРИИ

Я не знаю ни одного метода, который позволял бы вам связывать внешние свойства коллекции. В качестве обходного пути вы можете использовать систему 3 классов (да, я знаю, все более и более сложную).

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;}
}

привязать внешние поля к TestObj.header и связать поля коллекции с TestObj.col, Это обходной путь, но, как уже говорилось, я на самом деле не знаю, как напрямую реализовать то, что вы хотите. Хотел бы я, есть части моего собственного кода, которые выиграют от этого.

Другой пример

Вы также можете сделать это с двумя классами, но вам все равно придется вкладывать саму коллекцию

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

В этом случае привязать отдельные поля данных к TestObjи поля сбора в TestObj.col

Другие вопросы по тегам