【问题标题】:datatagridview has rows but datatsourse is showing empty?datatagridview 有行但 datatsourse 显示为空?
【发布时间】:2017-06-29 09:29:07
【问题描述】:

我从 UI 手动在 datagridview 中添加了行。 现在我希望数据源填充数据表,但数据源为空。

【问题讨论】:

    标签: c# winforms datagridview


    【解决方案1】:

    由于您已手动将行添加到 GridView 并且您尚未设置 DataSource,因此显然数据源将为空或 null,

    您只需要迭代所有行并将它们绑定到数据表。

                    DataTable dt = new DataTable();
                    dt.Columns.Add("Date", typeof(DateTime));
                    dt.Columns.Add("Particular", typeof(string));
                    dt.Columns.Add("Debit", typeof(int));
                    dt.Columns.Add("Credit", typeof(int));
                    dt.Columns.Add("Balance", typeof(string));
                    dt.Columns.Add("Summary", typeof(string));
    
    
            private void bindGridtoDataTable()
            {
                foreach (DataGridViewRow row in dataGridView1.Rows)
                    dt.Rows.Add(row.Cells["Date"].Value, row.Cells["Particular"].Value, row.Cells["Debit"].Value, row.Cells["Credit"].Value, row.Cells["Balance"].Value, row.Cells["Summary"].Value);
            }
    

    【讨论】:

    • 在每一行上使用循环。
    【解决方案2】:

    这是一个很好的例子:Save datagridView into sql database

    您需要区分行是否已被删除、修改或添加。

    var dataTable = ((DataTable)dataGridView1.DataSource).GetChanges();
    if(dataTable != null && dataTable.Rows.Count > 0)
    {
      foreach (DataRow row in dataTable.Rows)
            {
                switch (row.RowState)
                {
                    case DataRowState.Added:
                        // DO INSERT QUERY
                        break;
                    case DataRowState.Deleted:
                        // DO DELETE QUERY
                        break;
                    case DataRowState.Modified:
                        SqlCommand command = new SqlCommand("UPDATE YOURTABLE SET TypNastaveniaID = @typ, Nazov = @title, Hodnota = @amount");
                        command.Parameters.Add(new SqlParameter("@typ", row["TypNastaveniaID"]));
                        command.Parameters.Add(new SqlParameter("@title", row["Nazov"]));
                        command.Parameters.Add(new SqlParameter("@amount", row["Hodnota"]));
                        command.ExecuteNonQuery();
                        break;
                }
            }
        ((DataTable)dataGridView1.DataSource).AcceptChanges();
    }
    

    【讨论】:

    【解决方案3】:

    这里的一些答案建议您使用 DataGridView 中的 Rows。 我强烈建议您不要这样做,而是使用 BindingSource 和 BindingList!

    我认为问题在于您将集合直接分配给数据源,而不是通过BindingList

    如果你有一个班级,比如说MyClass,你有一个序列要在你的DataGridView 中显示,并且你想通过添加/删除/更改来添加/删除/更改该序列中的项目DataGridView 中的行,您应该执行以下操作

    • 将您的项目设为 `IEnumerable
    • 将它们包装在 BindingList 中
    • 将此分配给 bindingSource1.DataSource
    • 将 bindingSource 分配给 dataGridView1.DataSource

    这大部分都可以在视觉工作室设计器中完成。您唯一需要做的就是将数据包装在 BindingList 中,并将 BindingList 分配给 BindingSource 的 DataSource:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponents();
        }
    
        private void InitialeDataGridView
        {
            IEnumerable<MyClass> dataToShow = ...
            this.BindingSource1.DataSource = new BindingList<MyClass>(dataToShow.ToList());
        }
    
        private void Form1_Load(object sender, ...)
        {
            this.InitializeDataGridView();
        }
    
        private void button1_click(object sender, ...)
        {
            IEnumerable<MyClass> editedData = (BindingList<MyClass>)this.bindingSource1.DataSource;
            ProcessEditedData(editedData);
        }
    }
    

    您会看到所有已编辑的数据。但是,您的数据将无法排序。为此,您可以创建一个 SortableBindingList,在 Stackoverflow 上描述的某处。不过安装Nuget BindingListView要容易得多

    这会稍微改变您的代码,但会启用排序和过滤:

    您使用BindingListView&lt;MyClass&gt; 而不是BindingList。您的代码只会稍有变化:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponents();
            this.myItems= new BindingListView<MyClass>(this.components);
            this.bindingSource1.DataSource = this.myItems;
        }
    
        private readonly BindingListView<MyClass> myItems;
    
        private void InitialeDataGridView
        {
            IEnumerable<MyClass> dataToShow = ...
            this.myItems = dataToShow.ToList();
        }
    
        private void Form1_Load(object sender, ...)
        {
            this.InitializeDataGridView();
        }
    
        private void button1_click(object sender, ...)
        {
            IEnumerable<MyClass> editedData = (BindingListView<MyClass>)this.bindingSource1.DataSource;
            ProcessEditedData(editedData);
        }
    }
    

    然后,您可以通过单击列标题对列进行排序。查看已排序列标题中排序字形的自动更改,您将获得额外奖励。

    过滤:

    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        if (this.checkBox1.Checked)
        {   // show only items with Id == 0
            Predicate<MyClass> pr = p => p.Id == 0;
            this.persons.ApplyFilter(pr);
        }
        else
           this.persons.RemoveFilter();
    }
    

    就这么简单:添加/删除/更改/排序/过滤:只需几行代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多