Correct Approach to Using a List of Custom Classes as DataSource for DataGridView

Nov 26, 2025 · Programming · 11 views · 7.8

Keywords: C# | DataGridView | Data Binding | Custom Class | ICollection

Abstract: This article delves into common issues and solutions when binding a list of custom classes to DataGridView in C#. By analyzing Q&A data and reference articles, it explains why directly binding ICollection or OrderedDictionary to DataGridView leads to display problems and provides a complete implementation using custom structs as data sources. The article includes detailed code examples and step-by-step explanations to help developers understand the core mechanisms of data binding, ensuring data is correctly displayed in the grid view.

Problem Background and Common Misconceptions

In C# development, many developers attempt to bind ICollection or OrderedDictionary directly to the DataGridView data source, expecting automatic display of key-value pairs. However, this approach often results in blank columns or unrelated properties (e.g., Length) being shown. For instance, in the Q&A data, the user added m_Settings.Keys and m_Settings.Values to a list, but DataGridView failed to parse these collections correctly because the binding mechanism relies on public properties of objects, not internal collection structures.

Core Solution: Using Custom Classes

The best practice is to define a custom class that encapsulates each key-value pair as an independent object. As shown in Answer 1, create a class like MyStruct with public string properties (e.g., Name and Adres), then build a list of such classes. The binding mechanism uses reflection to access these public properties, automatically generating corresponding columns. Code example:

class MyStruct
{
    public string Name { get; set; }
    public string Adres { get; set; }

    public MyStruct(string name, string adress)
    {
        Name = name;
        Adres = adress;
    }
}

// In the form load event
var source = new BindingSource();
List<MyStruct> list = new List<MyStruct> { new MyStruct("fff", "b"), new MyStruct("c", "d") };
source.DataSource = list;
grid.DataSource = source;

This method ensures that DataGridView displays two columns with headers Name and Adres, populated correctly. The key is that properties must be public; otherwise, binding cannot access them.

In-Depth Analysis of Binding Mechanism

The data binding of DataGridView is based on .NET's reflection mechanism. When setting the DataSource, the control iterates through each object in the data source, checks its public properties, and automatically creates columns. If ICollection types are used, binding may only show collection-level properties (e.g., Count or Length) instead of element contents. A similar issue in the reference article confirms this: the user defined a MyFileInfo class, but the initial version lacked complete property setup, leading to no data display. After correction, proper binding was achieved through public properties like Name and FullName.

Implementation Steps and Code Optimization

From the Q&A data, the user initially erred by adding entire key and value collections to the list, rather than individual key-value pairs. The correct approach is to iterate through the OrderedDictionary, creating a custom object for each entry. Optimized code:

List<MyStruct> list = new List<MyStruct>();
for (int i = 0; i < m_Settings.Count; i++)
{
    // Assuming m_Settings.Keys and Values are accessible by index
    string key = m_Settings.Keys[i].ToString();
    string value = m_Settings.Values[i].ToString();
    list.Add(new MyStruct(key, value));
}
bindingSource1.DataSource = list;
dataGridView1.DataSource = bindingSource1;

This code ensures each MyStruct instance represents a setting item, and after binding, DataGridView auto-generates columns and populates data. Using BindingSource enhances flexibility, supporting sorting and filtering.

Common Issues and Debugging Tips

If data still does not display, check the following: ensure custom class properties are public and have getters and setters; verify the data source contains elements (use debugger to check list.Count); confirm DataGridView's AutoGenerateColumns property is true (default). In the reference article, the user confirmed via debugging that the data source had values, but display issues stemmed from incomplete property definitions, highlighting the importance of property accessibility.

Summary and Best Practices

In conclusion, using a list of custom classes as the DataGridView data source is a reliable method. Avoid binding complex collections directly; instead, simplify data structures through encapsulation. This improves code maintainability and leverages the advantages of .NET binding mechanisms. Developers should always test property visibility and use BindingSource for advanced data operations.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.