Я боролся с исключением NullReferenceException и надеюсь, что кто-то здесь сможет указать мне в правильном направлении. Я пытаюсь создать и заполнить DataTable, а затем показать результаты в элементе управления DataGridView. Ниже приведен базовый код, а выполнение останавливается с помощью исключения NullReferenceException в точке, где я вызываю новый UpdateResults_Delegate. Как ни странно, я могу отслеживать записи. Rows.Count успешно, прежде чем я верну его из QueryEventEntries, поэтому я могу хотя бы показать 1) записи не являются нулевой ссылкой, а 2) DataTable содержит строки данных. Я знаю, что я должен делать что-то неправильно, но я просто не знаю, что.
private void UpdateResults(DataTable entries)
{
dataGridView.DataSource = entries;
}
private void button_Click(object sender, EventArgs e)
{
PerformQuery();
}
private void PerformQuery()
{
DateTime start = new DateTime(dateTimePicker1.Value.Year,
dateTimePicker1.Value.Month,
dateTimePicker1.Value.Day,
0, 0, 0);
DateTime stop = new DateTime(dateTimePicker2.Value.Year,
dateTimePicker2.Value.Month,
dateTimePicker2.Value.Day,
0, 0, 0);
DataTable entries = QueryEventEntries(start, stop);
UpdateResults(entries);
}
private DataTable QueryEventEntries(DateTime start, DateTime stop)
{
DataTable entries = new DataTable();
entries.Columns.AddRange(new DataColumn[] {
new DataColumn("event_type", typeof(Int32)),
new DataColumn("event_time", typeof(DateTime)),
new DataColumn("event_detail", typeof(String))});
using (SqlConnection conn = new SqlConnection(DSN))
{
using (SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT event_type, event_time, event_detail FROM event_log " +
"WHERE event_time >= @start AND event_time <= @stop",
conn))
{
adapter.SelectCommand.Parameters.AddRange(new Object[] {
new SqlParameter("@start", start),
new SqlParameter("@stop", stop)});
adapter.Fill(entries);
}
}
return entries;
}
Обновление
Я хотел бы обобщить и предоставить дополнительную информацию, которую я узнал из обсуждения здесь, и отладки, так как я изначально разместил этот вопрос.
Я рефакторинг старого кода, который извлекал записи из базы данных, собирал эти записи в виде массива, а затем перебирал через массив, чтобы заполнить DataGridView по строкам. Реализация Threading была первоначально реализована для компенсации и поддержания пользовательского интерфейса в течение ненужного цикла. С тех пор я снял Thread/Invoke; все происходит в одном потоке выполнения (спасибо, Sam).
Я пытаюсь заменить медленный, громоздкий подход, используя DataTable, который я могу заполнить с помощью DataAdapter, и назначить DataGridView через его свойство DataSource (выше кода обновлено).
Я провел через записи строки DataTable, чтобы проверить, что таблица содержит ожидаемые данные, прежде чем назначать ее как DataSource DataSource.
foreach (DataRow row in entries.Rows)
{
System.Diagnostics.Trace.WriteLine(
String.Format("{0} {1} {2}", row[0], row[1], row[2]));
}
Один из столбцов DataGridView - это настраиваемый элемент DataGridViewColumn для стилизации значения event_type. Прошу прощения, я не упоминал об этом раньше в оригинальном посте, но я не знал, что это важно для моей проблемы. Я временно преобразовал этот столбец в стандартный элемент управления DataGridViewTextBoxColumn и больше не испытываю Exception.
Поля в DataTable добавляются в список полей, которые были предварительно заданы в представлении "Дизайн" DataGridView. Значения записей заполняются в этих добавленных полях. Когда время выполнения пытается отобразить ячейку, предоставляется нулевое значение (поскольку значение, которое должно быть визуализировано, выполняется так, что пара столбцов завершается).
В свете этого я повторяю и повторно помещаю вопрос. Я бы по достоинству оценил это, если другие, кто испытал это, могут проинструктировать меня о том, как связать DataTable с существующими определениями столбцов DataGridView.