пустой master/detail datagridview
От: Ash81  
Дата: 08.09.07 11:50
Оценка:
Добрый день!

Возникла проблема. Detail таблица формируется пустой, если в master таблице нет ни одной записи.
Связаны они через BindingSource стандартным образом

BindingSource masterSource = new BindingSource()
//создаем список с записями из БД
BindingList<MasterRecord> masterRecords = new BindingList<MasterRecord>(MasterRecord.FindAll());
masterSource.DataSource = masterRecords;
//в свойстве DetailRecords содержиться IList записей дочерней таблицы, указываем это
masterSource.DataMember = "DetailRecords"

//теперь очередь detail таблицы
BindingSource detailSource = new BindingSource()
//указываем в качестве источника данный BindingSource master таблицы
detailSource.DataSource = masterSource

//наконец очередь доходит до датагридов
dgvMaster.DataSource = masterSource;
dgvDetail.DataSource = detailSource;


Все работает отлично, если в обеих таблицах есть хотя бы по одной записи. В случае если записи нет, датагрид master таблицы позволяет вносить новые данные, а датагрид дочерней таблицы оказывается пустым. Теперь, даже если добавить запись в master таблицу, он все равно будет оставаться пустым.

Как я понимаю, это из за того, что коллекция DetailRecords в объектах MasterRecord не типизированная. Но сделать ее типизированной — это отдельная песня (я использую ORM Castle ActiveRecord для доступа к БД, а он не умеет работать с коллекциями BindingList и List)

Как вариант, можно в пустую таблицу программно вносить первую запись во время инициализации BindingSource'ов. Но решение, согласитесь, не очень элегантное =(

Ничего умнее придумать пока не получается =( Буду благодарен за подсказку.
Re: пустой master/detail datagridview
От: Ash81  
Дата: 10.09.07 08:55
Оценка:
Прошу прощения. Если бы я действительно сделал так как описал выше — проблемы бы не возникло.
Причина вот в чем:
Несколько моих классов реализуют интерфейс IParentRecord, еще несколько реализуют интерфейс — IChildRecord;
Каждый класс реализующий интерфейс IParentRecord, содержит коллекцию объектов класса реализующего IChildRecord;
(таким образом у меня формируются пары связанных таблиц)

Получаются нечто вроде:


IParentRecord
{
   BindingList<IChildRecord> СhildRecords { get; set; }
}

SomeParentClass1 : IParentRecord
{
   BindingList<IChildRecord> _childRecords;
   ...
}

SomeParentClass2 : IParentRecord
{
   BindingList<IChildRecord> _childRecords;
   ...
}


Засада в том, что я, как оказалось, совершенно напрасно передаю в BindingList — интерфейс. Как только я начинаю передавать ему конкретные классы, DataGridView инициализируется нормально (позволяет добавлять/удалять записи). Как мне кажется, дело в том, что BindingList (а может BindingSource), в случае, если в качестве типа BindingList'у передан интерфейс, "не знает" конструктор какого класса вызывать. Но вместо того, что бы выдать исключение, BindingList(или BindingSource) молча позволяет над ним надругаться. А в результате — пустой datagridview. Никак не могу придумать, как обойти эти грабли. Отказываться от достигнутого уровня абстрации очень не хочется, половину программы переписывать придется
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.