简体   繁体   English

如何从 DataGridView 读取 C# 中的单元格值

[英]How can i read cell value in C# from DataGridView

im trying to do a StackAutomata for a School assigment and I try find the cells via for but they cannot read it int i, K and J is created outside the do {} while cicle我试图为学校分配做一个 StackAutomata,我尝试通过 for 找到单元格,但他们无法读取它 int i、K 和 J 是在 do {} 之外创建的,而 cicle

for (int j = 0; j < gv1.Columns.Count; j++)
                {
                    if (input[i].ToString() == gv1.Rows[0].Cells[j].Value)
                    {
                        K = j;
                    }
                }

                J = K;
                


string a = verem.Pop();
for (int j = 0; j < gv1.Rows.Count; j++)
                    {
                        if (a == gv1.Rows[j].Cells[0].Value)
                        {
                            K = j;
                        }
                    }

What am i missing?我错过了什么?

It is seldom a good idea to directly read and write to the DataGridView yourself.自己直接读写 DataGridView 很少是个好主意。 It is better to separate your model from the way that your model is displayed.最好将 model 与 model 的显示方式分开。

If your data can exist without its display, it will be easier to change the way you display it, it will be easier to reuse the data in another control, or different format.如果您的数据可以在没有显示的情况下存在,那么更改显示方式会更容易,在另一个控件或不同格式中重用数据会更容易。 Easier to unit test the data handling (no form needed,).更容易对数据处理进行单元测试(无需表格)。 to change the internal layout of the data without having to change those who display this data.改变数据的内部布局,而不必改变那些显示这些数据的人。

This separation between View and Model is implemented in extrema in the MVVM model, but windows Forms also supports this via Data Binding. This separation between View and Model is implemented in extrema in the MVVM model, but windows Forms also supports this via Data Binding.

Whenever you have a control that displays information about a sequence of similar items, whether it is a ListBox, a DataGridView or even a GraphView, you'll find that it has a property DataSource .每当您拥有一个显示有关一系列相似项的信息的控件时,无论是 ListBox、DataGridView 还是 GraphView,您都会发现它具有属性DataSource

All you have to do is put the data that you want to show in the DataSource.您所要做的就是将要显示的数据放入 DataSource 中。 Other properties define how the data in the DataSource has to be displayed.其他属性定义必须如何显示 DataSource 中的数据。 If the operator changes the displayed data, then the original data is automatically updated.如果操作员改变了显示的数据,那么原始数据会自动更新。

Suppose your DataGridView has to show a collection of Customers: one Customer per row.假设您的 DataGridView 必须显示一组客户:每行一个客户。

Your DataGridView has several DataGridViewColumns .您的 DataGridView 有几个DataGridViewColumns Every column will show the value of one of the properties.每列将显示其中一个属性的值。 The name of the property to show is in property DataGridViewColumn.DataPropertyName .要显示的属性名称在属性DataGridViewColumn.DataPropertyName中。

All you have to do is make a sequence of similar items, and assign this to DataGridView.DataSource.您所要做的就是制作一系列相似的项目,并将其分配给 DataGridView.DataSource。

An example will help.一个例子会有所帮助。

Suppose you need to show a sequence of Students:假设您需要显示一系列学生:

class Customer
{
    public int Id {get; set;}
    public string Name {get; set;}
    public DateTime BirthDay {get; set;}
    ...
}

You want to show these three Student properties in columns.您想在列中显示这三个学生属性。 Using the visual studio designer you add the columns and assign the DataPropertyName.使用 Visual Studio 设计器添加列并分配 DataPropertyName。 The results can be found in InitializeComponents , or you can do it yourself:结果可以在InitializeComponents中找到,也可以自己做:

private readonly DataGridViewColumn columnId = new DataGridViewColumn();
private readonly DataGridViewColumn columnName = new DataGridViewColumn();
private readonly DataGridViewColumn columnBirthDay = new DataGridViewColumn();

// constructor
public MyForm()
{
    InitializeComponents();

    // define which column should display which Student property
    this.columnId.DataPropertyName = nameof(Student.Id);
    this.columnName.DataPropertyName = nameof(Student.Name);
    this.columnBirthDay.DataPropertyName = nameof(Student.BirthDay);

    // the the DataGridView to use these columns:
    this.dataGridView1.Columns.Add(this.columnId);
    this.dataGridView1.Columns.Add(this.columnName);
    this.dataGridView1.Columns.Add(this.columnBirthday);
}

Usually you set other column properties: you set the text of the Header, the column order, sometimes you define the display format, for instance: for the Birthday you don't want to show the time of day.通常您设置其他列属性:您设置 Header 的文本,列顺序,有时您定义显示格式,例如:对于生日,您不想显示一天中的时间。 But if you want, you can make column Id readonly, with a bold font, etc.但如果你愿意,你可以将列 ID 设为只读,使用粗体等。

Notice, that until now we have done everything without one actual Student.请注意,到目前为止,我们在没有一个实际学生的情况下完成了所有工作。

If you want to display the Students but don't want to edit them, it is enough to put them in a Collection and assign this collection to the DataSource of the DataGridView如果您想显示学生但不想编辑它们,将它们放在一个集合中并将这个集合分配给 DataGridView 的数据源就足够了

List<Student> students = ...
this.DataGridView1.DataSource = students;

However, if you want that operators can Add / Remove / Change / Reorder Students, you need a mechanism that the changes are updated in your students collection.但是,如果您希望操作员可以添加/删除/更改/重新排序学生,您需要一种机制来更新学生集合中的更改。 This is done automatically if you put your data in a BindingList如果您将数据放在BindingList中,这会自动完成

IList<Student> students = ...
BindingList<Student> displayedStudents = new BindingList<Student>(students);
this.DataGridView1.DataSource = displayedStudents;

All students are displayed.显示所有学生。 The operator can Add / Remove / Change the Students as he likes (apart from the columns that you made readonly).操作员可以根据需要添加/删除/更改学生(除了您只读的列)。 All changes are automatically updated in the BindingList.所有更改都会在 BindingList 中自动更新。

You can subscribe to events off the BndingList to react on these changes, but a more common scenario is that you do nothing until the operator tells you that he finished changing, for instance by pressing a button:您可以从 BndingList 订阅事件以对这些更改做出反应,但更常见的情况是您什么都不做,直到操作员告诉您他完成了更改,例如按下按钮:

private void ButtonOk_Clicked(object sender, ...)
{
    DataGridView dataGridView = (DataGridView)sender;
    BindingList<Student> students = (BindingList<Student>)dataGridView.DataSource;

    foreach (Student student in students)
    {
         this.ProcessStudent(student);
    }

If you have saved copies of the original students, you can detect which Student are changed, added, removed and decide what to do with them.如果您保存了原始学生的副本,您可以检测哪些学生被更改、添加、删除并决定如何处理它们。 If you need to do something with the selected rows:如果您需要对选定的行执行某些操作:

IEnumerable<Student> selectedStudents = this.dataGridView1.SelectedRows
    .Cast<DataGridViewRow>()
    .Select(row => row.DataBoundItem)
    .Cast<Student>();

One nice feature: suppose you want that your software assigns the Id of the Students, instead of the operator.一个不错的功能:假设您希望您的软件分配学生的 ID,而不是操作员。 Then whenever the operator wants to Add a new Row, you have to make the Student, with a unique Id.然后,每当操作员想要添加新行时,您都必须使用唯一的 Id 创建学生。 This is done by handling event BindingList.AddingNew这是通过处理事件BindingList.AddingNew来完成的

private void StudentCollection_AddingNew(object sender, AddingNewEventArgs e)
{
    // You need to make a Student with a unique Id:
    int newStudentId = this.CreateUniqueStudentId();
    e.NewObject = new Student
    {
        Id = newStudentId,
        // the operator has to fill in the rest of the properties
    }
}

Did you notice that you don't have to care about how the Students are displayed: you don't care which properties, what display format or column order.您是否注意到您不必关心学生的显示方式:您不必关心哪些属性、什么显示格式或列顺序。 If in future someone decides not to show the Birthday of the Student anymore, or reorder the columns, maybe change show the name of the Student in capital letters: all these methods will still work.如果将来有人决定不再显示学生的生日,或者重新排列列,可能会更改以大写字母显示学生的姓名:所有这些方法仍然有效。

for (int j = 0; j < gv1.Columns.Count; j++) {
  if (input[i].ToString() == gv1.Rows[0].Cells[j].Value.ToString()) {
    K = j;
  }
}

J = K;

string a = verem.Pop();
for (int j = 0; j < gv1.Rows.Count; j++) {
  if (a == gv1.Rows[j].Cells[0].Value.ToString()) {
    K = j;
  }
}

You cant compare gridview.Rows.Cells.Value with a string as it is an Object , just add the .ToString() Method and it should work.您无法将gridview.Rows.Cells.Value与字符串进行比较,因为它是Object ,只需添加.ToString()方法,它应该可以工作。

Also please find a better name for your variables it makes your code more readable.另外,请为您的变量找到一个更好的名称,它会使您的代码更具可读性。

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

相关问题 如何使单元格仅在填充后才能读取? 数据网格视图 C# - How can I make a cell to read only when it has been filled? DataGridView C# C#:如何获取未绑定的DataGridView单元的值? - C#: How do I get the value of an unbound DataGridView cell? C#如何从特定单元格数据中获取价值 - C# how to get value from specific cell datagridview C# - 如何从 DataGridView 获取单元格值? - C# - How to get cell value from DataGridView? 如何获取 DataGridView combobox 单元格值以写入 C# 的 MessageBox 中? - How can I get DataGridView combobox cell value to be written in the MessageBox in C#? 如何使用c#中的行索引和列索引从datagridview获取单元格值? - How do I get the cell value from a datagridview using row index and column index in c#? 如何从C#中的DataGridView单元中提取以分号分隔的值 - How can I extract semicolon separated values from DataGridView cell in C# 如何从数据库中将用“逗号”分隔的许多值引入c#中的datagridview的单元格? - How can I bring from a database many values separated by “commas” to a cell of a datagridview in c#? 如何在C#中同时将datagridview的多个单元格值从一种形式传递到另一种形式? - How can I pass multiple cell values of datagridview from one form to another at same time in C#? 我如何更改单元格datagridview的值 - how can i change the value of a cell datagridview
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM