Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Bind DataTable to Existing DataGridView Column Definitions

I've been struggling with a NullReferenceException and hope someone here will be able to point me in the right direction. I'm trying to create and populate a DataTable and then show the results in a DataGridView control. The basic code follows, and Execution stops with a NullReferenceException at the point where I invoke the new UpdateResults_Delegate. Oddly enough, I can trace entries.Rows.Count successfully before I return it from QueryEventEntries, so I can at least show 1) entries is not a null reference, and 2) the DataTable contains rows of data. I know I have to be doing something wrong, but I just don't know what.

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;
}

Update

I'd like to summarize and provide some additional information I've learned from the discussion here and debugging efforts since I originally posted this question.

I am refactoring old code that retrieved records from a database, collected those records as an array, and then later iterated through the array to populate a DataGridView row by row. Threading was originally implemented to compensate and keep the UI responsive during the unnecessary looping. I have since stripped out Thread/Invoke; everything now occurs on the same execution thread (thank you, Sam).

I am attempting to replace the slow, unwieldy approach using a DataTable which I can fill with a DataAdapter, and assign to the DataGridView through it's DataSource property (above code updated).

I've iterated through the entries DataTable's rows to verify the table contains the expected data before assigning it as the DataGridView's DataSource.

foreach (DataRow row in entries.Rows)
{
    System.Diagnostics.Trace.WriteLine(
        String.Format("{0} {1} {2}", row[0], row[1], row[2]));
}

One of the column of the DataGridView is a custom DataGridViewColumn to stylize the event_type value. I apologize I didn't mention this before in the original post but I wasn't aware it was important to my problem. I have converted this column temporarily to a standard DataGridViewTextBoxColumn control and am no longer experiencing the Exception.

The fields in the DataTable are appended to the list of fields that have been pre-specified in Design view of the DataGridView. The records' values are being populated in these appended fields. When the run time attempts to render the cell a null value is provided (as the value that should be rendered is done so a couple columns over).

In light of this, I am re-titling and re-tagging the question. I would still appreciate it if others who have experienced this can instruct me on how to go about binding the DataTable to the existing column definitions of the DataGridView.

like image 544
Timothy Avatar asked Apr 28 '10 03:04

Timothy


People also ask

What is C in simple words?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.

Is C or C++ same?

The main difference between C and C++ is that C is a procedural programming language that does not support classes and objects. On the other hand, C++ is an extension of C programming with object-oriented programming (OOP) support.

What is C language used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...


1 Answers

You need to ensure each column's DataPropertyName property is set to the corresponding name of the DataColumn's ColumnName.

You may also need to set the DataGridView's AutoGenerateColumns property to false.

I found the solution here.

like image 99
Timothy Avatar answered Oct 08 '22 16:10

Timothy