2009-11-05 4 views
1

Я пытаюсь привязать коллекцию (которая наследуется от BindingList) к DataGridView. Заголовки сетки отображаются хорошо, и я получаю количество строк, которые я ожидаю. Однако ячейки пусты. У кого еще возникла эта проблема? Если да, то как вы его разрешили? Я разговаривал с кем-то, у кого была такая же проблема, но они не могут вспомнить, как они это разрешили. Я попытался создать простую версию, которая показывает проблему, но не повезло. Так что извините, я не включил никакого кода.Строки DataGridView отображаются, но нет данных

EDIT # 1:

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

public interface ISearchResultCollection : IList<ISearchResult> 
{ 
... 
} 

public class SearchResultCollection : BindingList<ISearchResult>, ISearchResultCollection 
{ 
... 
} 

public interface ISearchResult 
{ 
    ILineNum LineNumber {get; set;} 
    string Text {get; set;} 
} 

public class SearchResult 
{ 
... 
} 

ISearchResultCollection results = objectToSearch.Find("searchstring"); 
dataGridView1.DataSource = results; 

EDIT # 2:

Я думаю, что у меня есть преимущество. Все публичные свойства моего интерфейса, которые представляют элемент (ISearchResult), также являются типами интерфейсов. Я добавил свойство string, и его данные волшебным образом появляются. Итак, в приведенном выше примере будут отображаться данные в текстовом столбце. Но данные столбца LineNumber не будут, поскольку он имеет тип интерфейса (ILineNum). Я решил, что ToString() будет вызван, чтобы заполнить сетку. Какие-нибудь идеи сейчас?

+0

Можете ли вы привести больше примеров объектов, которые вы пытаетесь связать? Например, как выглядит «коллекция, наследующая от BindingList»? Как вы привязываете свой объект к DataGridView? Непосредственно или через BindingSource? Вы уверены, что у вашего объекта есть данные внутри него? Это очень сложно ответить без кода для анализа. :) –

+0

Я внес некоторые изменения, чтобы включить оболочку кода. Я не уверен, что это поможет. Я проверил, что в отладчике есть данные. – bsh152s

ответ

1

Когда вы привязываете объект к некоторому элементу управления, интерфейсы привязки данных автоматически вызывают «ToString()» на вашем объекте, чтобы вы получили достойное строковое представление в любом элементе управления, к которому вы привязываетесь. В случае DataGridView вы увидите представление ToString для базового объекта в соответствующей ячейке. Однако, когда вы привязываетесь к интерфейсу, такой вызов ToString() не производится. Это означает, что ваш DataGridView отображает пустую ячейку, но это довольно вводит в заблуждение, поскольку связанный объект на самом деле там, как и должно быть - он просто не имеет значения для отображения в ячейке.

Чтобы исправить это, вам нужно иметь дело с форматированием значения отображения самостоятельно. В DataGridView это может быть достигнуто путем обработки события CellFormatting. Это событие запускается всякий раз, когда какая-либо ячейка должна отформатировать ее значение, поэтому вы должны быть осторожны, чтобы не перекладывать слишком тяжелую логику в этот обработчик. В вашем случае все, что вам нужно сделать, это вызвать «ToString()» в базовом объекте. Таким образом, вы можете обрабатывать событие CellFormatting затем использовать что-то вроде этого в обработчике:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    if (e.Value != null && dataGridView1.Columns[e.ColumnIndex] == theRelevantColumn) 
    { 
     e.Value = e.Value.ToString(); 
    } 
} 

В приведенном выше фрагменте коде мы проверяем для определенного столбца перед выполнением логики, но это не является обязательным, собственный сценарий может отличаться. Главное отметить, что мы получаем исходный объект, переданный в аргументах событий, и все, что нам нужно сделать, это установить форматированное значение обратно в аргументы события. В этом случае форматированное значение генерируется путем вызова «ToString()» в базовом объекте. В DataGridView вы увидите это отформатированное значение в соответствующей ячейке.

Надеюсь, что это поможет.

0

Вам необходимо установить AllowUserToAddRows на false;

Смежные вопросы