DataGridView排序导致NullReferenceException

问题描述 投票:1回答:1

我想有一个DataGridView,用户可以通过单击表头来对其进行排序。 DataGridViews数据绑定到DataView,数据的最后一行应该是一个总和行(总和未在此代码中实现!)需要始终是最后一行(换句话说,它需要是免除排序)。 基于this answer我在我的课程中实现了以下代码:

using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace PipelineManagement.Debug
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            tlp1.RowStyles.Clear();
            for (var i = 0; i < 1; i++)
            {
                tlp1.RowStyles.Add(new RowStyle(SizeType.Absolute, 200));
                var gbNew = new GroupBox();
                gbNew.Text = "gb" + i;
                gbNew.Size = new Size(tlp1.Size.Width - 2, 185);
                gbNew.Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Left;
                m_dgv = new DataGridView();
                m_dgv.Parent = gbNew;
                m_dgv.AutoSize = true;
                m_dgv.Location = new Point(5, 25);
                m_dgv.Size = new Size(gbNew.Size.Width - 10, gbNew.Size.Height - 70);
                m_dgv.Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Left;
                m_dt = new DataTable();
                for (var j = 0; j < 2; j++)
                {
                    var NewColumn = new DataColumn("Column" + j, typeof(Double));
                    m_dt.Columns.Add(NewColumn);
                }
                var k = 5;
                for (var j = 0; j < 5; j++)
                {
                    var NewRow = m_dt.NewRow();
                    NewRow[0] = Convert.ToDouble(k--);
                    m_dt.Rows.Add(NewRow);
                }
                m_dt.AcceptChanges();
                m_dgv.ColumnHeaderMouseClick += dgv_ColumnHeaderMouseClick;
                m_dgv.CellValueChanged += CellValueChangedHandler;
                m_dgv.DataSource = m_dt.DefaultView;

                tlp1.Controls.Add(gbNew);
            }
        }

        private void dgv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            var col = m_dgv.Columns[e.ColumnIndex].Name;
            if (col != "")
            {
                if (m_Direction == ListSortDirection.Ascending)
                {
                    m_Direction = ListSortDirection.Descending;
                }
                else
                {
                    m_Direction = ListSortDirection.Ascending;
                }                
                sort_dgv(col, m_Direction);
            }
        }

        private void CellValueChangedHandler(Object sender, DataGridViewCellEventArgs e)
        {
            var temp = m_dt.Rows[0].Field<Double>(0);
            m_dt.Rows[m_dt.Rows.Count-1].SetField<Double>(0, m_dt.Rows[m_dt.Rows.Count - 1].Field<Double>(0) + 1);
        }

        private void sort_dgv(String ColumnName, ListSortDirection Direction)
        {
            if (!m_dt.Columns.Contains("sortMe"))
            {
                m_dt.Columns.Add("sortMe", typeof(Int32));
            }
            var dr = m_dt.Rows[m_dt.Rows.Count - 1];

            m_dt.DefaultView.Sort = "";
            for (int r = 0; r < m_dt.Rows.Count; r++)
            {
                m_dt.Rows[r]["sortMe"] = 0;
            }
            dr["sortMe"] = int.MaxValue;

            if (Direction == ListSortDirection.Descending)
            {
                m_dt.DefaultView.Sort = "sortMe," + ColumnName + " DESC";
            }
            else
            {
                m_dt.DefaultView.Sort = "sortMe," + ColumnName;
            }
            m_dt.Columns.Remove("sortMe");
        }

        private DataGridView m_dgv;
        private DataTable m_dt;
        private ListSortDirection m_Direction = ListSortDirection.Ascending;
    }
}

问题:一旦我点击任何标题对表进行排序 - 按预期工作 - 当我更改任何单元格中的值(并调用CellValueChangedHandler)时,我得到一个System.NullReferenceException:'对象引用未设置为实例一个东西。'在线

m_dt.Rows[m_dt.Rows.Count-1].SetField<Double>(0, m_dt.Rows[m_dt.Rows.Count - 1].Field<Double>(0) + 1);

我上面的一行能够从完全相同的行(存储在变量temp中)中获取值,但是一旦我尝试写入单元格,就抛出异常。

问题:有人知道为什么我可以从单元格中读取值但在写入时会出现异常吗?

c# datagridview dataview
1个回答
1
投票

请尝试以下代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication44
{
    public partial class Form1 : Form
    {
        DataTable m_dt = new DataTable();

        public Form1()
        {
            InitializeComponent();

            m_dgv.CellValueChanged += CellValueChangedHandler;

            m_dt.Columns.Add("Col_A", typeof(double));
            m_dt.Columns.Add("Col_B", typeof(string));
            m_dt.Rows.Add(new object[] { 1 });

            m_dgv.DataSource = m_dt;
        }

        private void CellValueChangedHandler(Object sender, DataGridViewCellEventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            DataGridViewCellEventArgs arg = e as DataGridViewCellEventArgs;
            int row = arg.RowIndex;
            int col = arg.ColumnIndex;

            if (row >= 0 && row == dgv.Rows.Count - 2) //new row already added to DGV
            {
                if (row == 0)
                {
                    if (col != 0)
                    {
                        dgv.Rows[row].Cells[0].Value = 1;
                    }
                }
                else
                {
                    double temp = (double)dgv.Rows[row - 1].Cells[0].Value;
                    dgv.Rows[row].Cells[0].Value = temp + 1;
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            m_dt = m_dt.AsEnumerable().OrderBy(x => x.Field<string>("Col_B")).CopyToDataTable();
            m_dgv.DataSource = null;
            m_dgv.DataSource = m_dt;
        }

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