C # Привязать DataTable к существующим определениям столбцов DataGridView - PullRequest
13 голосов
/ 28 апреля 2010

Я боролся с 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 строка за строкой. Потоки изначально были реализованы, чтобы компенсировать и поддерживать отзывчивость интерфейса во время ненужного зацикливания. С тех пор я удалил Thread / Invoke; теперь все происходит в одном и том же потоке выполнения (спасибо, Сэм ).

Я пытаюсь заменить медленный, громоздкий подход, используя DataTable, который я могу заполнить DataAdapter, и назначить DataGridView через его свойство DataSource (код выше обновлен).

Я перебрал строки записей DataTable, чтобы убедиться, что таблица содержит ожидаемые данные, прежде чем назначить их в качестве источника данных DataGridView.

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 и больше не испытываю исключение.

Поля в DataTable добавляются в список полей, которые были предварительно заданы в представлении «Дизайн» DataGridView. Значения записей заполняются в этих добавленных полях. Когда время выполнения пытается визуализировать ячейку, предоставляется нулевое значение (так как значение, которое должно быть отображено , должно быть , делается так, чтобы пара столбцов была выше).

В свете этого я переименовываю и помечаю тегом вопрос. Я по-прежнему был бы признателен, если бы другие, кто испытал это, могли научить меня, как выполнить связывание DataTable с существующими определениями столбцов DataGridView.

Ответы [ 2 ]

27 голосов
/ 01 мая 2010

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

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

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

0 голосов
/ 28 апреля 2010

Если ошибка возникает внутри UpdateResults, значит, dataGridView равно нулю.

private void UpdateResults(DataTable entries)
{
    dataGridView.DataSource = entries; // when is dataGridView set?
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...