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

C#中DataGridView仅显示列头不加载数据问题排查

问题排查:DataGridView仅显示列头无数据

问题背景

在C# WinForms项目中,尝试通过DataGridView展示SQL Server存储过程TechnicalRejects的返回数据,但仅能看到列头,无法加载具体数据。已通过EXEC命令验证存储过程可正常返回数据,问题出在代码逻辑中。

相关代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace RonnaForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public class columnTitle
        {
            public int Id { get; set; }
            public string Site { get; set; }
            public string ProductCode { get; set; }
            public string ProductName { get; set; }
            public string PrimaryRejectionReason { get; set; }
            public string SecondaryRejectionReason { get; set; }
            public string AdditionalComments { get; set; }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DataTable Dtable = new DataTable(); //创建一个名为Dtable的新DataTable
    
            try
            {
                // 连接SQL Server数据库
                using (var con = new SqlConnection("Data Source=ffgsqltest2;Initial Catalog=Test_Playground;Integrated Security=True;")) //创建与Test_Playground数据库的连接

                // 获取目标存储过程
                using (var cmd = new SqlCommand("TechnicalRejects", con)) 
                // 用于填充列数据
                using (var da = new SqlDataAdapter(cmd)) 
                {
                    cmd.Parameters.AddWithValue("@Site", CBox1.Text.ToString());
                    cmd.Parameters.AddWithValue("@PrimaryRejectionReason", CBox2.Text.ToString());

                    cmd.CommandType = CommandType.StoredProcedure;

                    // 填充DataTable
                    da.Fill(Dtable); 
                }

                DataGridView.DataSource = Dtable;
            }
            catch (Exception ex)
            {
                MessageBox.Show("发生错误:" + ex.Message);
            }

            // 为第一个下拉框添加选项
            CBox1.Text = "All"; 
            CBox1.Items.Add("Town1");
            CBox1.Items.Add("Town2");
            CBox1.Items.Add("Town3");
            CBox1.Items.Add("Town4");
            CBox1.Items.Add("Town5");

            // 默认选中"All"
            CBox1.SelectedIndex = 0; 

            // 为第二个下拉框添加选项
            CBox2.Text = "All"; 
            CBox2.Items.Add("All");
            CBox2.Items.Add("Label Issue");
            CBox2.Items.Add("Out of Specification");
            CBox2.Items.Add("Contamination");
            CBox2.Items.Add("Damaged");
            CBox2.Items.Add("Order Administration");
            CBox2.Items.Add("Other");

            // 默认选中"All"
            CBox2.SelectedIndex = 0; 
        }

        private void CBoxRejection_SelectedIndexChanged(object sender, EventArgs e)
        { 
            // 此为CBox1,用于选择站点
            DataTable Otable = new DataTable();
    
            try
            {
                SqlConnection con = new SqlConnection("Data Source=ffgsqltest2;Initial Catalog=Test_Playground;Integrated Security=True;");
                SqlCommand cmd = new SqlCommand("TechnicalRejects", con);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@Site", CBox1.Text.ToString());

                SqlDataAdapter dga = new SqlDataAdapter();
                dga.SelectCommand = cmd;
                dga.Fill(Otable);

                DataGridView.DataSource = Otable;
            }
            catch (Exception ex)
            {
                MessageBox.Show("搜索站点时发生错误:" + ex.Message);
            }
        }

        private void CBox2_SelectedIndexChanged(object sender, EventArgs e)
        { 
            // 此为CBox2,用于选择拒收原因
            DataTable Otable = new DataTable();

            SqlConnection con = new SqlConnection("Data Source=ffgsqltest2;Initial Catalog=Test_Playground;Integrated Security=True;");

            SqlCommand cmd = new SqlCommand("TechnicalRejects", con);

            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@Site", CBox1.Text.ToString());
            cmd.Parameters.AddWithValue("@PrimaryRejectionReason", CBox2.Text.ToString());

            SqlDataAdapter dga = new SqlDataAdapter();
            dga.SelectCommand = cmd;
            dga.Fill(Otable);

            DataGridView.DataSource = Otable;
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            // 创建用于存储结果的新DataTable
            DataTable Dtable = new DataTable(); 

            try
            {
                // 指定数据库地址并声明调用存储过程
                SqlConnection con = new SqlConnection("Data Source=ffgsqltest2;Initial Catalog=Test_Playground;Integrated Security=True;");
                SqlCommand cmd = new SqlCommand("TechnicalRejects", con);
                cmd.CommandType = CommandType.StoredProcedure;

                // 添加搜索筛选参数
                cmd.Parameters.AddWithValue("@Site", CBox1.SelectedItem.ToString());
                cmd.Parameters.AddWithValue("@PrimaryRejectionReason", CBox2.SelectedItem.ToString());

                SqlDataAdapter dga = new SqlDataAdapter(cmd);
                dga.Fill(Dtable); // 用搜索结果填充DataTable

                // 将DataTable绑定到DataGridView
                DataGridView.DataSource = Dtable;
            }
            catch (Exception ex)
            {
                // 处理错误
                MessageBox.Show("搜索时发生错误:" + ex.Message);
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

问题原因及修复方案

1. Form1_Load方法中下拉框初始化顺序错误

问题:调用存储过程的逻辑在下拉框初始化之前执行,此时CBox1.Text和CBox2.Text为空字符串,传递空参数给存储过程导致返回空结果。
修复:将下拉框初始化代码移到存储过程调用之前:

private void Form1_Load(object sender, EventArgs e)
{
    // 先初始化下拉框
    CBox1.Items.Add("All");
    CBox1.Items.Add("Town1");
    CBox1.Items.Add("Town2");
    CBox1.Items.Add("Town3");
    CBox1.Items.Add("Town4");
    CBox1.Items.Add("Town5");
    CBox1.SelectedIndex = 0; 

    CBox2.Items.Add("All");
    CBox2.Items.Add("Label Issue");
    CBox2.Items.Add("Out of Specification");
    CBox2.Items.Add("Contamination");
    CBox2.Items.Add("Damaged");
    CBox2.Items.Add("Order Administration");
    CBox2.Items.Add("Other");
    CBox2.SelectedIndex = 0; 

    DataTable Dtable = new DataTable(); 
    
    try
    {
        using (var con = new SqlConnection("Data Source=ffgsqltest2;Initial Catalog=Test_Playground;Integrated Security=True;"))
        using (var cmd = new SqlCommand("TechnicalRejects", con)) 
        using (var da = new SqlDataAdapter(cmd)) 
        {
            cmd.Parameters.AddWithValue("@Site", CBox1.Text);
            cmd.Parameters.AddWithValue("@PrimaryRejectionReason", CBox2.Text);
            cmd.CommandType = CommandType.StoredProcedure;
            da.Fill(Dtable); 
        }
        DataGridView.DataSource = Dtable;
    }
    catch (Exception ex)
    {
        MessageBox.Show("发生错误:" + ex.Message);
    }
}

2. CBoxRejection_SelectedIndexChanged事件参数不完整

问题:该事件处理CBox1的选择变更,但调用存储过程时仅传递了@Site参数,未传递@PrimaryRejectionReason,若存储过程依赖两个参数返回数据,会导致结果为空。
修复:补充参数传递并规范资源释放:

private void CBoxRejection_SelectedIndexChanged(object sender, EventArgs e)
{ 
    DataTable Otable = new DataTable();
    
    try
    {
        using (SqlConnection con = new SqlConnection("Data Source=ffgsqltest2;Initial Catalog=Test_Playground;Integrated Security=True;"))
        using (SqlCommand cmd = new SqlCommand("TechnicalRejects", con))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@Site", CBox1.Text);
            cmd.Parameters.AddWithValue("@PrimaryRejectionReason", CBox2.Text);

            using (SqlDataAdapter dga = new SqlDataAdapter(cmd))
            {
                dga.Fill(Otable);
                DataGridView.DataSource = Otable;
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("搜索站点时发生错误:" + ex.Message);
    }
}

3. 数据库资源未正确释放

问题:CBox2_SelectedIndexChanged等方法中,SqlConnection、SqlCommand未用using包裹,可能导致资源泄漏,影响数据读取稳定性。
修复:所有数据库操作对象均用using语句包裹,确保资源自动释放(参考上面CBoxRejection_SelectedIndexChanged的修复代码)。

4. btnSearch中参数获取的潜在空引用问题

问题:使用CBox1.SelectedItem.ToString(),若下拉框未选中任何项(极端场景)会抛出NullReferenceException。
修复:改用CBox1.Text更稳妥:

cmd.Parameters.AddWithValue("@Site", CBox1.Text);
cmd.Parameters.AddWithValue("@PrimaryRejectionReason", CBox2.Text);

额外调试建议

  • 填充DataTable后,可通过Dtable.Rows.Count查看是否有数据,快速定位是参数问题还是存储过程返回问题。
  • 确认存储过程对"All"参数的处理逻辑,比如是否通过WHERE (@Site = 'All' OR Site = @Site)实现全量查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:27:04