C#中DataGridView绑定List<User>后无数据显示的问题
DataGridView绑定User列表后无数据显示的解决方法
问题说明
创建User类并从数据库拉取数据生成User列表后,将列表设置为DataGridView的DataSource,网格无任何数据显示。尝试过BindingSource绑定、手动创建列均无效,但通过Label可确认列表数据正确。
原代码
Form1.cs
namespace Material { public partial class Form1 : Form { public Form1() { InitializeComponent(); List<User> users = new List<User>(); Database data = new Database(); List<User> names = Database.GetFromDB(); dataGridView1.AutoGenerateColumns = true; dataGridView1.DataSource = names; label1.Text = names[0].name.ToString(); } } }
User.cs
namespace Material { public class User { public int id; public string name; public string email; public User(int id, string name, string email) { this.id = id; this.name = name; this.email = email; } public void PrintUser() { Console.WriteLine(id + " " + name + " " + email); } } }
Database.cs
namespace Material { public class Database { public static string dbPath = "Data Source= C:\\Users\\Jonathan\\Documents\\csharp\\Material\\Material\\bids.db"; // Path to your database file public static void MakeDB() { SQLiteConnection connection = new SQLiteConnection(dbPath); connection.Open(); // This will create the database file if it doesn't exist string createTableSql = @"CREATE TABLE IF NOT EXISTS Users2 ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL, Email TEXT UNIQUE );"; SQLiteCommand command = new SQLiteCommand(createTableSql, connection); command.ExecuteNonQuery(); } public static void AddtoDB(string name) { SQLiteConnection connection = new SQLiteConnection(dbPath); connection.Open(); // This will create the database file if it doesn't exist string createTableSql = "INSERT INTO Users (Id, Name, Email) VALUES (Null, @Name, @Email)"; SQLiteCommand command = new SQLiteCommand(createTableSql, connection); command.Parameters.AddWithValue("@Name", name); command.Parameters.AddWithValue("@Email", name + "@gmail.com"); command.ExecuteNonQuery(); } public static List<User> GetFromDB() { SQLiteConnection connection = new SQLiteConnection(dbPath); connection.Open(); var sql = "SELECT * FROM Users"; using var command = new SQLiteCommand(sql, connection); using var reader = command.ExecuteReader(); List<User> myObjectList = []; if (reader.HasRows) { while (reader.Read()) { var id = reader.GetInt32(0); var name = reader.GetString(1); var email = reader.GetString(2); myObjectList.Add(new User(id, name, email)); } } else { Console.WriteLine("No authors found."); } return myObjectList; } } }
数据库数据
| id | name | |
|---|---|---|
| 1 | Jonathan | jon@gmail.com |
| 2 | Happy | Happy@gmail.com |
| 3 | Leighton | Leighton@gmail.com |
解决方法
核心问题是User类使用公共字段(field)而非属性(property),DataGridView的数据绑定依赖属性的get/set访问器,无法直接识别公共字段。
修改User类为属性形式
namespace Material { public class User { public int Id { get; set; } public string Name { get; set; } public string Email { get; set; } public User(int id, string name, string email) { Id = id; Name = name; Email = email; } public void PrintUser() { Console.WriteLine(Id + " " + Name + " " + Email); } } }
额外优化建议
- 保持属性名与数据库列名大小写一致,避免自动生成列时名称不匹配;若需映射可使用
[DisplayName]特性。 - 可选使用BindingSource作为中间层,提升数据绑定灵活性:
var bindingSource = new BindingSource(); bindingSource.DataSource = names; dataGridView1.DataSource = bindingSource;
- 完善数据库连接释放逻辑,用
using语句包裹SQLiteConnection:
public static List<User> GetFromDB() { List<User> myObjectList = []; using (SQLiteConnection connection = new SQLiteConnection(dbPath)) { connection.Open(); var sql = "SELECT * FROM Users"; using var command = new SQLiteCommand(sql, connection); using var reader = command.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { var id = reader.GetInt32(0); var name = reader.GetString(1); var email = reader.GetString(2); myObjectList.Add(new User(id, name, email)); } } else { Console.WriteLine("No authors found."); } } return myObjectList; }
内容的提问来源于stack exchange,提问作者user22425260
相关产品推荐
相关产品推荐

