DataGridView 有行,但数据源显示为空

问题描述 投票:0回答:3

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

c# winforms datagridview
3个回答
1
投票

由于您已手动将行添加到 GridView 并且尚未设置数据源,因此显然数据源将为空或 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);
        }

0
投票

这是如何执行此操作的一个很好的示例:将 datagridView 保存到 sql 数据库中

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

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();
}

0
投票

这里的一些答案建议您摆弄

DataGridView
中的行。 我强烈建议你不要这样做,而是使用 BindingSource 和 BindingList!

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

如果您有一个类,请说

MyClass
,其中您有一个要在
DataGridView
中显示的序列,并且您希望通过添加/删除/更改中的行来添加/删除/更改此序列中的项目您的 DataGridView 您应该执行以下操作

  • 将您的项目设为“IEnumerable”
  • 将它们包装在 BindingList 中
  • 将其分配给绑定源1.DataSource
  • 将绑定源分配给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<MyClass>
代替 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();
}

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

© www.soinside.com 2019 - 2024. All rights reserved.