DataGridView筛选触发System.NullReferenceException问题求助(未用数据库)
空引用异常原因及解决方法
问题背景
应用从网站抓取数据后,通过BindingSource将Tabel类实例绑定到DataGridView,未使用数据库存储。绑定代码:
tabelBindingSource.Add(new Tabel() { Postion = (l + 1).ToString(), Title = title[l], ItemPrice = itemprice[l], ShippingCost = shippingcost[l], NewUserBonus = newuserbonus[l], Rating = productrating[l], SoldAmount = soldamount[l], SellerRating = sellerrating[l] });
自定义Tabel类:
namespace AliExpress_Search_Bot { class Tabel { public string Postion { get; set; } public string Title { get; set; } public string ItemPrice { get; set; } public string Rating { get; set; } public string SoldAmount { get; set; } public string ShippingCost { get; set; } public string NewUserBonus { get; set; } public string SellerRating { get; set; } } }
执行筛选时触发System.NullReferenceException,报错代码:
(DataGridView.DataSource as DataTable).DefaultView.RowFilter = String.Format("ShippingCost like '%"+textBox8.Text + "%;'");
问题原因
- 类型转换失败:
DataGridView的数据源是BindingSource(内部存储Tabel实例集合),as DataTable会返回null——因为BindingSource和DataTable是完全不同的类型,后续访问DefaultView必然抛出空引用异常。 - 筛选语法错误:即使转换成功,筛选字符串末尾多余的分号
;会导致RowFilter语法错误。
解决方案
方案一:直接使用BindingSource的Filter属性(推荐)
BindingSource原生支持Filter属性,无需转换为DataTable,直接设置即可:
// 修正语法,去掉多余分号,同时转义单引号避免语法错误 string filterValue = textBox8.Text.Replace("'", "''"); tabelBindingSource.Filter = $"ShippingCost LIKE '%{filterValue}%'";
注:替换单引号是为了避免用户输入包含单引号时,导致Filter语法报错。
方案二:转换为DataTable后绑定(可选)
如果必须使用DataTable的RowFilter,可以先将Tabel集合转换为DataTable再绑定:
- 添加集合转
DataTable的工具方法:
using System.ComponentModel; using System.Data; using System.Collections.Generic; public static DataTable ToDataTable<T>(IList<T> data) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T)); DataTable table = new DataTable(); foreach (PropertyDescriptor prop in props) table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); foreach (T item in data) { DataRow row = table.NewRow(); foreach (PropertyDescriptor prop in props) row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; table.Rows.Add(row); } return table; }
- 修改绑定逻辑:
// 假设用List<Tabel>存储抓取的数据 List<Tabel> tabelData = new List<Tabel>(); // 填充数据到tabelData... DataTable tabelTable = ToDataTable(tabelData); DataGridView.DataSource = tabelTable;
- 执行筛选(此时转换不会返回null):
string filterValue = textBox8.Text.Replace("'", "''"); ((DataTable)DataGridView.DataSource).DefaultView.RowFilter = $"ShippingCost LIKE '%{filterValue}%'";
内容的提问来源于stack exchange,提问作者herry jack
相关产品推荐
相关产品推荐

