使用搜索文本框中的值过滤数据网格视图列表:“对象引用未设置为对象的实例。”

我已经设置了一个文本框来搜索我的数据网格上的名称,但我收到了错误: 'Object reference not set to an instance of an object.'


List<Member> members = new List<Member>();


public class Member

{

    public int id { get; set; }

    public string name { get; set; }

    public int age { get; set; }

    public Image image_url { get; set; }

}


// In a keyup event of the text box

(memberGrid.DataSource as DataTable).DefaultView.RowFilter = string.Format("name = '{0}'", searchBox.Text);

我已尝试更改DataTable为List或Member。我也尝试过List/Member在前面使用铸造,DataTable但它似乎不起作用。


最好的方法是什么?


编辑:


这就是我将 SQL 选择中的每一行数据添加到列表中的方式。


members.Add(new Member

{

    id = Convert.ToInt32(reader["id"]),

    name = reader["name"].ToString(),

    age = Convert.ToInt32(reader["age"]),

    image_url = (Image)Properties.Resources.ResourceManager.GetObject(reader["image_url"].ToString())

});

要添加到网格中,我遍历列表并为每个成员添加一行:


for (int i = 0; i < members.Count; i++)

{

    memberGrid.Rows.Add(new object[]

    {

        members[i].image_url,

        members[i].name,

        members[i].age

    });

}


慕盖茨4494581
浏览 164回答 2
2回答

拉丁的传说

由于您没有设置DataSourceofDataGridView并且它为空,因此当您在此语句中使用它时收到异常:(memberGrid.DataSource as DataTable).DefaultView....不是将行一一添加到DataGridView,而是将数据分配给其DataSource。然后根据您使用的数据结构,您可以过滤数据。您可以使用以下任一解决方案:作为一个选项,来解决这个问题,你可以将数据加载到DataTable并将其设置为DataSource的DataGridView。然后可以按照您尝试的方式进行过滤。此外,如果出于任何原因您更喜欢在其上使用List<Member>并应用过滤器,则在加载数据并转换为 a 后List<Member>,将列表保留在表单成员字段中,List<Member> members;然后使用linq以下方式进行过滤:dataGridView1.DataSource = members.Where(x=>x.Name ==searchBox.Text).ToList();有关更多详细信息,请阅读帖子中的以下部分。为什么我收到 NullReferenceException以下代码行将抛出一个NullReferenceExceptionif DataSourceis null or DataSourceis not a DataTable:(memberGrid.DataSource as DataTable).DefaultView.RowFilter = ...在您的情况下,您正在通过添加行来填充数据库并且没有使用其数据源,因此DataSourcenull 和上面的代码会引发异常。要查找有关如何调试的更多信息NullReferenceException,请查看什么是 NullReferenceException,以及如何修复它?.加载数据你提到过:这就是我将 SQL 选择中的每一行数据添加到列表中的方式。members.Add(new Member {&nbsp; &nbsp; &nbsp; id = Convert.ToInt32(reader["id"]),&nbsp; &nbsp; &nbsp; name = reader["name"].ToString(),&nbsp;&nbsp; &nbsp; &nbsp; ...看来您正在使用 SQL 查询和SqlDataReader. 那么你不需要使用 a List<Member>, aDataTable对你来说就足够了。您可以将代码更改为以下代码以加载数据:public DataTable GetData(){&nbsp; &nbsp; var dt = new DataTable();&nbsp; &nbsp; var cn = @"Your Connection String";&nbsp; &nbsp; var cmd = @"Your Select Command";&nbsp; &nbsp; using (var da = new SqlDataAdapter(cmd, cn))&nbsp; &nbsp; &nbsp; &nbsp; da.Fill(dt);&nbsp; &nbsp; return dt;}注意:如果出于任何原因您有兴趣继续使用List<Member>,请重构您的代码以返回List<Member>in GetData:public List<Member> GetData(){&nbsp; &nbsp; var dt = new DataTable();&nbsp; &nbsp; var cn = @"Your Connection String";&nbsp; &nbsp; var cmd = @"Your Select Command";&nbsp; &nbsp; using (var da = new SqlDataAdapter(cmd, cn))&nbsp; &nbsp; &nbsp; &nbsp; da.Fill(dt);&nbsp; &nbsp; return dt.AsEnumerable().AsEnumerable().Select(r=>{&nbsp; &nbsp; &nbsp; &nbsp; id = r.Field<int>("id"),&nbsp; &nbsp; &nbsp; &nbsp; name = r.Field<string>("name"),&nbsp; &nbsp; &nbsp; &nbsp; age = r.Field<int>("age")&nbsp; &nbsp; }).ToList();}在 DataGridView 中显示数据你提到过:要添加到网格中,我遍历列表并为每个成员添加一行:for (int i = 0; i < members.Count; i++) {&nbsp; &nbsp; memberGrid.Rows.Add(new object[]&nbsp; &nbsp; &nbsp; ...当您将数据加载到一个DataTable(或者甚至在List<Member>)你不需要接一个地添加行一个DataGridView,只是将数据分配到DataSource的财产DataGridView。为此,您可以覆盖OnLoad表单的方法或处理Load事件并将数据加载到数据表中并将其设置为数据源DataGridView:DataTable dt;protected override void OnLoad(EventArgs e){&nbsp; &nbsp; base.OnLoad(e);&nbsp; &nbsp; dt = LoadData();&nbsp; &nbsp; dataGridView1.DataSource = dt;}注意:如果出于任何原因您更喜欢返回List<Member>from GetData,代码将是:List<Member> members;protected override void OnLoad(EventArgs e){&nbsp; &nbsp; base.OnLoad(e);&nbsp; &nbsp; members = LoadData();&nbsp; &nbsp; dataGridView1.DataSource = members;}过滤数据然后过滤数据,使用就足够了dt.DefaultView.RowFilter:dt.DefaultView.RowFilter = string.Format("name = '{0}'", searchBox.Text);注意:如果出于任何原因您更喜欢对其List<Member>应用过滤器,在加载列表并将列表保存在表单成员中,就像我在上面的部分中所做的那样,用于linq过滤数据:dataGridView1.DataSource = members.Where(x=>x.Name ==searchBox.Text).ToList();

UYOU

Reza Aghaei 解释了如何解决问题,但如果将来有人需要另一种方法来处理这些情况,我就是这样做的。所以正如提到的问题是 (memberGrid.DataSource as DataTable).DefaultView.RowFilter = string.Format("name = '{0}'", searchBox.Text);它可能发生的原因有两个。你DataSource没有被分配所以它is null您为对象分配了其他类型DataTable,然后您尝试将其“返回”以DataTable使其返回 null对于完美的流程,始终将数据绑定到数据源并通过它进行操作。这是我在datagridviews中的做法。首先我尝试将数据直接加载到 DataTable因此,如果您从 SQL 加载它,只需使用DataAdapter并填写DataTableusing(SqlConnetion....){&nbsp; &nbsp; con.Open();&nbsp; &nbsp; using(SqlDataAdapter da ....)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; DataTable dt = new DataTable();&nbsp; &nbsp; &nbsp; &nbsp; da.Fill(dt);&nbsp; &nbsp; &nbsp; &nbsp; dataGridView.DataSource = dt;&nbsp; &nbsp; &nbsp; &nbsp; //I use this method often because every change i am doing is directly into database and then i just refresh dgv if i need it by loading data again.&nbsp; &nbsp; }}如果DataTable由于某种原因直接加载数据对您来说很难(需要自己创建数据表并用 foreach 但太多列或类似的东西填充它)或者您想在代码中操作数据但不能在DataTable您可以使用List<T>所以只需创建对象public class Car{&nbsp; &nbsp; public string Model { get; set; }&nbsp; &nbsp; public Color Color { get; set; }&nbsp; &nbsp; public string LicencePlate { get; set; }&nbsp; &nbsp; public doube HP { get; set; }&nbsp; &nbsp; public Car()&nbsp; &nbsp; {&nbsp; &nbsp; }}然后假设我们需要从jsonString我们做的加载汽车List<Car> myCars = JsonConverter.Deserialize<List<Car>>(stringFromWebForExample);现在我们有了可以在其中操作但需要将其放入 datagridview 的列表。同样,我们可以通过dataGridView.DataSource = myCars但DataTable比List在 datagridview 中显示更实用,所以我所做的是使用以下代码将该列表转换为数据表:public static DataTable ConvertToDataTable<T>(this IList<T> data){&nbsp; &nbsp; PropertyDescriptorCollection properties =&nbsp; &nbsp; &nbsp; &nbsp;TypeDescriptor.GetProperties(typeof(T));&nbsp; &nbsp; DataTable table = new DataTable();&nbsp; &nbsp; foreach (PropertyDescriptor prop in properties)&nbsp; &nbsp; &nbsp; &nbsp; table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);&nbsp; &nbsp; foreach (T item in data)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; DataRow row = table.NewRow();&nbsp; &nbsp; &nbsp; &nbsp; foreach (PropertyDescriptor prop in properties)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;&nbsp; &nbsp; &nbsp; &nbsp; table.Rows.Add(row);&nbsp; &nbsp; }&nbsp; &nbsp; return table;}就叫它 dataGridView.DataSource = myCars.ConvertToDataTable();这是处理数据和显示数据的两种实用方法 DataGridView
打开App,查看更多内容
随时随地看视频慕课网APP