С# Связать DataTable с существующими определениями столбцов DataGridView

Я боролся с исключением 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.

Ответ 1

Вам нужно убедиться, что для каждого свойства столбца DataPropertyName установлено соответствующее имя DataColumn ColumnName.

Вам также может потребоваться установить для свойства DataGridView AutoGenerateColumns значение false.

Я нашел решение здесь.

Ответ 2

Если ошибка возникает внутри UpdateResults, тогда это звучит так: dataGridView имеет значение null.

private void UpdateResults(DataTable entries)
{
    dataGridView.DataSource = entries; // when is dataGridView set?
}