You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中高效刷新DataGridView子集数据并指定显示列的方法

优化DataGridView绑定与列显示的实现方案

一、核心优化逻辑

用_dbContext.Candidates.Local.ToBindingList()绑定后,EF Core的ChangeTracker会自动跟踪实体的新增、修改、删除操作,无需每次调用查询方法刷新数据库,直接就能同步到DataGridView,彻底解决原方案的效率问题。要控制显示指定列,可通过以下几种方式实现:

二、方式一:手动指定DataGridView列(最可控)

  1. 关闭自动生成列,避免多余列显示
dataGridView1.AutoGenerateColumns = false;
  1. 手动创建需要显示的列,绑定实体对应属性
// 编号列(绑定Id属性)
var idCol = new DataGridViewTextBoxColumn
{
    HeaderText = "编号",
    DataPropertyName = "Id", // 必须和实体类的属性名完全一致
    ReadOnly = true // 根据需求设置是否只读
};
dataGridView1.Columns.Add(idCol);

// 名字列(绑定FirstName属性)
var firstNameCol = new DataGridViewTextBoxColumn
{
    HeaderText = "名",
    DataPropertyName = "FirstName"
};
dataGridView1.Columns.Add(firstNameCol);

// 姓氏列(绑定LastName属性)
var lastNameCol = new DataGridViewTextBoxColumn
{
    HeaderText = "姓",
    DataPropertyName = "LastName"
};
dataGridView1.Columns.Add(lastNameCol);
  1. 绑定数据源(确保先加载初始数据到Local集合)
// 首次加载数据到上下文Local集合
_dbContext.Candidates.Load();
// 绑定到DataGridView
dataGridView1.DataSource = _dbContext.Candidates.Local.ToBindingList();

三、方式二:通过实体类属性标记控制列显示

如果不想手动创建列,可通过特性标记实体类属性,控制自动生成列的显示:

  1. 在实体类中,给不需要显示的属性添加[Browsable(false)]特性
public class Candidate
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    // 该属性不会在DataGridView中显示
    [Browsable(false)]
    public string Email { get; set; }
}
  1. 开启自动生成列并绑定数据源
dataGridView1.AutoGenerateColumns = true;
_dbContext.Candidates.Load();
dataGridView1.DataSource = _dbContext.Candidates.Local.ToBindingList();

这种方式适合只需要隐藏少数属性的场景,若需精确指定显示列,推荐方式一。

四、方式三:投影到DTO类(解耦实体与UI)

如果实体类属性过多,或需要对显示数据做转换,可定义仅包含所需属性的DTO类:

  1. 创建DTO类
public class CandidateDto
{
    public int Id { get; set; }
    public string FullName => $"{FirstName} {LastName}"; // 可组合属性
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
  1. 加载数据并投影到DTO集合,同时监听实体变化同步更新
// 初始加载并投影
var dtoList = _dbContext.Candidates
    .Select(c => new CandidateDto
    {
        Id = c.Id,
        FirstName = c.FirstName,
        LastName = c.LastName
    })
    .ToList();
// 绑定到BindingList
var bindingList = new BindingList<CandidateDto>(dtoList);
dataGridView1.DataSource = bindingList;

// 监听上下文的实体变化事件,同步更新DTO集合
_dbContext.ChangeTracker.StateChanged += (sender, e) =>
{
    if (e.Entry.Entity is Candidate candidate)
    {
        // 根据实体状态(新增/修改/删除)更新dtoList和bindingList
        // 示例:处理修改操作
        if (e.Entry.State == EntityState.Modified)
        {
            var dto = bindingList.FirstOrDefault(d => d.Id == candidate.Id);
            if (dto != null)
            {
                dto.FirstName = candidate.FirstName;
                dto.LastName = candidate.LastName;
            }
        }
    }
};

这种方式适合需要UI层与实体类解耦的场景,但需要额外处理实体变化的同步逻辑。

五、注意事项

  • 使用Local.ToBindingList()前,必须确保数据已加载到上下文,可通过_dbContext.Candidates.Load()或执行任意查询(如_dbContext.Candidates.ToList())完成初始加载。
  • 新增实体后,只需调用_dbContext.Candidates.Add(newCandidate)并保存上下文,Local集合会自动更新,DataGridView也会同步显示新增行。
  • 修改实体后,直接修改实体属性并保存,DataGridView会自动同步修改内容,无需重新查询。

内容的提问来源于stack exchange,提问作者Unis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:33:29