C# 导致(当通过导航到另一行提交该行时)事件状态更新,以便一个网格始终显示True,一个网格显示False(一个网格显示all,您可以看到勾号开关)

C# 导致(当通过导航到另一行提交该行时)事件状态更新,以便一个网格始终显示True,一个网格显示False(一个网格显示all,您可以看到勾号开关),c#,datagridview,nullpointerexception,C#,Datagridview,Nullpointerexception,我把它作为单独的形式来做,因为你说的是“单独的类”——在这个上下文中,类和形式没有区别 对象教训是DataGridView不应该是您将数据推入其中的东西。您将数据保存在其他地方(如datatable),并通过DGV显示/交互(在用户单击和键入的意义上),但如果您希望以编程方式与数据交互,则将数据从datatable中取出,而不是从视图中取出(在非常特殊的情况下除外) 如果需要执行“访问当前行”之类的操作,可以通过BindingSource执行。。您可能需要涉及DGV的非常有限的情况是,例如,如果

我把它作为单独的形式来做,因为你说的是“单独的类”——在这个上下文中,类和形式没有区别

对象教训是DataGridView不应该是您将数据推入其中的东西。您将数据保存在其他地方(如datatable),并通过DGV显示/交互(在用户单击和键入的意义上),但如果您希望以编程方式与数据交互,则将数据从datatable中取出,而不是从视图中取出(在非常特殊的情况下除外)


如果需要执行“访问当前行”之类的操作,可以通过BindingSource执行。。您可能需要涉及DGV的非常有限的情况是,例如,如果用户选择了10行;您获得10行并要求他们提供其databounditem,这将在datatable中提供datarow(它提供DataRowView,其中有一个.Row,这是datarow,需要一些强制转换)。您不需要通过单元格拖出数据。Value

更好的方法是使用
BindingList
作为
DataSource
并且永远不要与DGV交互进行数据操作。代码在做什么?数据模型在哪里?DGV包含什么?更好的方法是将
BindingList
用作
DataSource
,并且永远不要与DGV交互进行数据操作。代码在做什么?数据模型在哪里?DGV包含什么?让我确保我理解这一点。如果我使用您的示例,我想做的是从我的products表(从数据库中)中提取数据,并将其设置为数据表(原始数据)。然后,当我想要选择一个产品时,我可以打开表单选择该行,它应该将该行带回主表单?我理解对了吗?如果它是这样工作的话,它确实看起来更容易。另外,我能问一下为什么从DGV而不是数据表中提取信息是一种糟糕的做法吗?很难知道您实际上在试图解决什么问题,但我认为这是一个典型的UI比喻(?)“这里有两个列表,一个是‘你可以选择的所有事物’,另一个是‘你已经选择的所有事物’,选择某个事物会将它从一个列表移动到另一个列表“。该示例指出,您可以将所有数据放在一个位置,并使用一个布尔值跟踪它是否被选中,然后UI中有两个元素可以/不可以基于布尔值显示内容。这使得它看起来像是从一个列表移动到另一个列表,但实际上它只存在于一个位置,无论这两个列表是并排的,还是在不同的形式上,其中一个打开和关闭(隐藏/显示可能更好,这样我们就不会一直制造新的东西)其实并不重要,因为我们没有这样的概念,我们将有一个在这里存储数据的网格和另一个在那里存储数据的网格,我们将数据从一个复制到另一个,如果我们已经将数据复制到这个网格,我们将有一些复杂的过程来隐藏该网格中的数据。它开始回答您的第二个问题,即为什么不使用windows控件直接在中存储数据。这是一个叫做MVC的编程概念(不是同名的微软ASPNET产品,尽管它实现了这个概念)——你有你的数据所在的模型,一个查看数据的设备(网格)和一个控制数据的设备(通常也是网格,除非网格是只读的。其他按钮等可以控制数据)。现在,您可以将数据直接存储在网格中,但这样做并不是很有用,而且会使很多事情变得更加困难,因为当所有事情都面向“此处的数据、此处的显示、其他位置的控制”时,找到与之相反的方法是逆流而上的。想象一下……让我确保我理解这一点。如果我使用您的示例,我想做的是从我的products表(从数据库中)中提取数据,并将其设置为数据表(原始数据)。然后,当我想要选择一个产品时,我可以打开表单选择该行,它应该将该行带回主表单?我理解对了吗?如果它是这样工作的话,它确实看起来更容易。另外,我能问一下为什么从DGV而不是数据表中提取信息是一种糟糕的做法吗?很难知道您实际上在试图解决什么问题,但我认为这是一个典型的UI比喻(?)“这里有两个列表,一个是‘你可以选择的所有事物’,另一个是‘你已经选择的所有事物’,选择某个事物会将它从一个列表移动到另一个列表“。该示例指出,您可以将所有数据放在一个位置,并使用一个布尔值跟踪它是否被选中,然后UI中有两个元素可以/不可以基于布尔值显示内容。这使得它看起来像是从一个列表移动到另一个列表,但实际上它只存在于一个位置,无论这两个列表是并排的,还是在不同的形式上,其中一个打开和关闭(隐藏/显示可能更好,这样我们就不会一直制造新的东西)其实并不重要,因为我们没有这样的概念,我们将有一个在这里存储数据的网格和另一个在那里存储数据的网格,我们将数据从一个复制到另一个,如果我们已经将数据复制到这个网格,我们将有一些复杂的过程来隐藏该网格中的数据。它开始回答您的第二个问题,即为什么不使用windows控件直接在中存储数据。这是一个叫做MVC的编程概念(不是同名的微软ASPNET产品,尽管它实现了这个概念)——你有你的数据所在的模型,一个查看数据的设备(网格)和一个控制数据的设备(通常也是网格,除非网格是只读的。其他按钮等可以控制数据)。现在,您可以将数据直接存储在网格中,但这样做并不是很有用,而且会使很多事情变得更加困难,因为当所有事情都是ge的时候
        if (material.RowSelected)
        {
            //Checks to see if there are any rows in the material DGV already.
            if (Q_MatDGV.Rows.Count > 0)
            {

                //TODO: Make it so if you have to add a new item then the column headers don't get added again.
                //I think you need to make a new array list then rebind the DGV after it's cleared out. 
                // Loop through the info that is already in the table and then you will have to get the data from the material.sourcegrid.columns and add that to the array list
                // once that is done we can then re link the dataset to the old DGV. 

                var source = new BindingSource();
                sourceGrid = this.Q_MatDGV; ;
                AddRows = new List<DataGridViewRow>();

               

                foreach (DataGridViewRow sourceRow in sourceGrid.Rows)
                {
                    if (Convert.ToBoolean(sourceRow.Cells["CheckBox"].Value) == true)
                    {
                        if (!sourceRow.IsNewRow)
                        {
                            var targetRow = (DataGridViewRow)sourceRow.Clone();

                            foreach (DataGridViewCell cell in sourceRow.Cells)
                            {
                                targetRow.Cells[cell.ColumnIndex].Value = cell.Value;
                               // MessageBox.Show(cell.Value.ToString());
                            }
                            AddRows.Add(targetRow);
                        }
                    }
                }

                foreach(DataGridViewRow row in material.SourceGrid.Rows)
                {
                    if (Convert.ToBoolean(row.Cells["CheckBox"].Value) == true)
                    {
                        AddRows.Add((DataGridViewRow)row.Clone());
                     
                    }
                }



                source.DataSource = AddRows;
               // Q_MatDGV.DataSource = null;
               // Q_MatDGV.Rows.Clear();
                Q_MatDGV.DataSource = source;
                MessageBox.Show(Q_MatDGV.Rows.Count.ToString());
                MessageBox.Show(Q_MatDGV.Rows[1].Cells[2].Value.ToString());
            }
    public Form1()
    {
        InitializeComponent();



        var dt = new DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("Chosen", typeof(bool));
        dt.Rows.Add("Matthew", true);
        dt.Rows.Add("Mark", false);
        dt.Rows.Add("Luke", false);
        dt.Rows.Add("John", false);

        var nonChosenDV = new DataView(dt);
        nonChosenDV.RowFilter = "[Chosen] = false";

        var chosenDV = new DataView(dt);
        chosenDV.RowFilter = "[Chosen] = true";

        var nonChosenDgv = new DataGridView();
        nonChosenDgv.DataSource = nonChosenDV;

        var chosenDgv = new DataGridView();
        chosenDgv.DataSource = chosenDV;


        var chosenF = new Form();
        chosenF.Text = "Only the chosen ones";
        chosenF.Controls.Add(chosenDgv);
        chosenF.Show();

        var nonChosenF = new Form();
        nonChosenF.Text = "These guys don't make the cut";
        nonChosenF.Controls.Add(nonChosenDgv);
        nonChosenF.Show();


        //add a dgv to this form to show all the data all the time
        var allDgv = new DataGridView();
        allDgv.DataSource = dt; //it will bind to the dt.DefaultView by the way
        this.Controls.Add(allDgv);
        this.Text = "All the raw data";


    }