简体   繁体   English

在 C# 的 DataGridView 中显示多于一行

[英]Showing more than one row in DataGridView in C#

Why I can't show more than one row on DataGridView in C#?为什么我不能在 C# 的 DataGridView 上显示超过一行?

Here is my code:这是我的代码:

btnAdd_Click Event: btnAdd_Click 事件:

    QuestionGroup _question = new QuestionGroup(); 
    _question.QGID = QGID; // int
    _question.QGName = QGName; // string
    ToQuestionList(_question);
    MessageBox.Show("Item Added successfully.", Application.ProductName, MessageBoxButtons.OK, 
                     MessageBoxIcon.Information);

ToQuestionList function:到问题列表 function:

    void ToQuestionList(QuestionGroup q)
    {
        Questions.Add(q);
        dataGridView1.DataSource = Questions;
    }

Question class:问题 class:

    public class QuestionGroup
        {
            public int QGID { get; set; }
            public string QGName { get; set; }
        }

Your problem is caused by the fact the DataGridView looks at the object that you want to set as its datasource.您的问题是由 DataGridView 查看您要设置为其数据源的 object 引起的。 It discovers that is the same object binded at the first click and so it doesn't change its display.它发现与第一次单击时绑定的 object 相同,因此它不会更改其显示。 Setting the Datasource with the same object doesn't force the DataGridView to look if there are more elements in the object.使用相同的 object 设置数据源不会强制 DataGridView 查看 object 中是否有更多元素。

A first fix could be:第一个修复可能是:

void ToQuestionList(QuestionGroup q)
{
    Questions.Add(q);
    dataGridView1.DataSource = null;
    dataGridView1.DataSource = Questions;
}

This will force the grid to rebind everything and the new elements will be displayed.这将强制网格重新绑定所有内容并显示新元素。
However there is a better approach using a BindingSource instance.但是,使用 BindingSource 实例有更好的方法。

You need to declare, at the class level, an object of type BindingSource like this您需要像这样在 class 级别声明 BindingSource 类型的 object

public class Form1: Form
{
     BindingSource data = new BindingSource();
     List<QuestionGroup> Questions = new List<QuestionGroup>();
     ....

then in the Form Load event you should add these lines然后在 Form Load 事件中,您应该添加这些行

public void Form_Load(object sender, EventArgs e)
{
     data.DataSource = Questions;
     dataGridView1.DataSource = data;
     ....

and finally you could change the ToQuestionList to (but at this point you can also remove it)最后您可以将 ToQuestionList 更改为(但此时您也可以将其删除)

void ToQuestionList(QuestionGroup q)
{
    bs.Add(q);
}

You are correct, if you want to show data in a DataGridView it is wise not to edit the rows and the cells directly, but to use a DataSource.你是对的,如果你想在 DataGridView 中显示数据,明智的做法是不要直接编辑行和单元格,而是使用 DataSource。

What type of DataSource you use depends on what you want to do with your data.您使用哪种类型的 DataSource 取决于您要对数据执行的操作。

  • If you only want to show the initial data, don't want to change it, then you can use any list / array for it, maybe even an IEnumerable or ICollection is enough.如果您只想显示初始数据,不想更改它,那么您可以使用任何列表/数组,甚至 IEnumerable 或 ICollection 就足够了。
  • If you want to change the data to be shown, you need to use an object that implements IBindingList.如果要更改要显示的数据,则需要使用实现 IBindingList 的 object。 This ensures that changes that your software makes to the data are shown in the DataGridView, and changes made by the operator in the DataGridView are updated in the source data.这可确保您的软件对数据所做的更改显示在 DataGridView 中,并且操作员在 DataGridView 中所做的更改会在源数据中更新。

For the latter case, it is enough to show your data in a BindingList对于后一种情况,在BindingList中显示您的数据就足够了

// the DataGridView that shows Customers:
private DataGridView CustomerView => this.customerView;

// The data in the DataGridView:
private BindingList<Customer> DisplayedCustomers
{
    get => (BindingList<Customer>)this.CustomerView.DataSource;
    set => this.CustomerView.DataSource = value;
}

// constructor:
public MyForm()
{
    InitializeComponent();   // creates member this.customerView;

    // initally show an empty customers collection
    this.DisplayedCustomers = new BindingList<Customer>();
}

After a while (on form loading? after a button press? Fetch Customers, and show the data:过了一会儿(表单加载?按下按钮后?获取客户,并显示数据:

private void InitCustomerView()
{
    var customers = this.GetCustomers().ToList();
    this.DisplayedCustomers = new BindingList<Customer> customers;
}

If you've defined your columns correctly, this is enough to show your data, one row per customer:如果您正确定义了列,这足以显示您的数据,每个客户一行:

dataGridViewColumnId.DataPropertyName = nameof(Customer.Id);
dataGridViewColumnName.DataPropertyName = nameof(Customer.Name);
...

To add / remove a displayed Customer:要添加/删除显示的客户:

private void AddCustomer(Customer customer)
{
    this.DisplayedCustomers.Add(customer);
}

private void RemoveCustomer(int customerId)
{
    int index = this.FindCustomerIndex(customerId);
    this.DisplayedCustomers.RemoveItem(index);
}

private int FindCustomerIndex(int customerId)
{
    // TODO: use (Collection<Customer>)this.DisplayedCustomers to find index
    // of customer with Id == customerId        
}

To fetch all Customers after the operator signaled he finished editing the Customers:在操作员发出他完成编辑客户的信号后获取所有客户:

private void ButtonFinishedEditing_Clicked(object sender, ...)
{
    ICollection<T> customers = this.DisplayedCustomers();
    this.ProcessEditedCustomers(customers);
}

Conclusion:结论:

Put your data in a BindingList<T> , and put this in the DataSource of the datagridview.将您的数据放入BindingList<T>中,并将其放入 datagridview 的 DataSource 中。 After every accepted edited row, the data is updated in the BindingList.在每个接受的编辑行之后,BindingList 中的数据都会更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM