使用搜索文本框中的值过滤数据网格视图列表:“对象引用未设置为对象的实例。” [英] Filter data grid view list with the value from the search text box: 'Object reference not set to an instance of an object.'
问题描述
我已经设置了一个文本框来搜索数据网格上的名称,但是收到错误消息:'对象引用未设置为对象的实例。'
I have set up a text box to search names on my data grid but I am receiving the error: '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
更改为列表
或成员
。我也尝试过在 DataTable
前面使用 List / Member
进行强制转换,但这似乎不起作用。
I have attempted to change DataTable
to List
or Member
. I have also tried casting using List/Member
in front of DataTable
but it doesn't seem to work.
什么是最好的方法?
编辑:
这是我将SQL选择中的每一行数据添加到列表中的方式。
This is how I add each row of data from my SQL select into the list.
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())
});
要添加到网格中,我遍历列表并为每个成员添加一行:
To add to the grid, I loop through the list and add a row per member:
for (int i = 0; i < members.Count; i++)
{
memberGrid.Rows.Add(new object[]
{
members[i].image_url,
members[i].name,
members[i].age
});
}
推荐答案
由于您未设置 DataSource
的 DataGridView
,它为空,然后在此语句中使用它时收到异常:(memberGrid.DataSource作为DataTable)。DefaultView...
。
Since you didn't set DataSource
of DataGridView
and it's null, then you received an exception when you used it in this statement: (memberGrid.DataSource as DataTable).DefaultView...
.
不是将一行一行地添加到 DataGridView
,而是将数据分配给其 DataSource
。然后根据您使用的数据结构,可以过滤数据。
Instead of adding rows one by one to the DataGridView
, assign data to its DataSource
. Then depending to the data structure which you are using, you can filter data.
您可以使用以下任一解决方案:
You can use either of the following solutions:
-
作为解决此问题的选项,您可以将数据加载到
DataTable
中并将其设置为<$DataGridView
的c $ c> DataSource 。然后可以按照您尝试的方式进行过滤。
As an option, to fix the problem, you can load data into a
DataTable
and set it asDataSource
of theDataGridView
. Then the filtering can be done the same way that you are trying to do.
如果出于某种原因,您更喜欢使用 List< Member>
并对其进行过滤,在加载数据并转换为 List< Member>
之后,将列表保留在表单成员字段中像 List< Member>成员;
然后使用 linq
进行过滤:
Also if for any reason you prefer to have a List<Member>
and apply filter on that, after loading data and converting to a List<Member>
, keep the list in a form member field like List<Member> members;
then for filtering using linq
:
dataGridView1.DataSource = members.Where(x=>x.Name ==searchBox.Text).ToList();
有关更多详细信息,请阅读
For more details read the following sections in the post.
为什么我收到NullReferenceException
下面的代码行会抛出 NullReferenceException
如果 DataSource
为空或 DataSource
不是 DataTable
:
The following line of code will throw a NullReferenceException
if DataSource
is null or DataSource
is not a DataTable
:
(memberGrid.DataSource as DataTable).DefaultView.RowFilter = ...
在您的情况下,您通过添加行来填充数据库,而没有使用其数据源,因此 DataSource
为null,并且上面的代码引发异常。
In your case, You are filling the database by adding rows and didn't used its data source, so DataSource
is null and above code throws exception.
查找有关如何调试的更多信息 NullReferenceException
,看看什么是NullReferenceException,以及如何解决它?。
To find more information about how to debug NullReferenceException
, take a look at What is a NullReferenceException, and how do I fix it?.
加载数据
您已提及:
这是我将SQL选择中的每一行数据添加到列表中的方式。
This is how I add each row of data from my SQL select into the list.
members.Add(new Member {
id = Convert.ToInt32(reader["id"]),
name = reader["name"].ToString(),
...
似乎您正在使用SQL查询和 SqlDataReader
。然后,您不需要使用 List< Member>
,一个 DataTable
就足够了。您可以将代码更改为以下代码以加载数据:
It seems you are using a SQL query and a SqlDataReader
. Then you don't need to use a List<Member>
, a DataTable
would be enough for you. You can change your code to the following code to load data:
public DataTable GetData()
{
var dt = new DataTable();
var cn = @"Your Connection String";
var cmd = @"Your Select Command";
using (var da = new SqlDataAdapter(cmd, cn))
da.Fill(dt);
return dt;
}
注意:如果您出于任何原因感兴趣为了继续使用 List< Member>
,重构代码以在<$ c $中返回 List< Member>
c> GetData :
Note: If for any reason you are interested to keep working with List<Member>
, refactor your code to return a List<Member>
in GetData
:
public List<Member> GetData()
{
var dt = new DataTable();
var cn = @"Your Connection String";
var cmd = @"Your Select Command";
using (var da = new SqlDataAdapter(cmd, cn))
da.Fill(dt);
return dt.AsEnumerable().AsEnumerable().Select(r=>{
id = r.Field<int>("id"),
name = r.Field<string>("name"),
age = r.Field<int>("age")
}).ToList();
}
在DataGridView中显示数据
您已经提到:
要添加到网格中,我遍历列表并添加一个每个成员的行数:
To add to the grid, I loop through the list and add a row per member:
for (int i = 0; i < members.Count; i++) {
memberGrid.Rows.Add(new object[]
...
当您将数据加载到 DataTable
(甚至在 List< Member>
)中时,您不会需要将一行一行添加到 DataGridView
,只需将数据分配给<$ c $的 DataSource
属性c> DataGridView 。
When you load data into a DataTable
(or even in a List<Member>
) you don't need to add rows one by one to the DataGridView
, just assign the data to DataSource
property of the DataGridView
.
为此,您可以覆盖 OnLoad
方法形成或处理 Load
事件并将数据加载到数据表中并将其设置为 DataGridView
的数据源:
To do so, you can override OnLoad
method of the form or handle Load
event and load data into a data table and set it as data source of the DataGridView
:
DataTable dt;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
dt = LoadData();
dataGridView1.DataSource = dt;
}
注意:如果出于某种原因您更愿意返回来自 GetData
的 List< Member>
,代码将为:
Note: If for any reason you preferred returning a List<Member>
from GetData
, the code will be:
List<Member> members;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
members = LoadData();
dataGridView1.DataSource = members;
}
过滤数据
然后过滤数据,使用 dt.DefaultView.RowFilter
就足够了:
Then to filter data, it's enough to use dt.DefaultView.RowFilter
:
dt.DefaultView.RowFilter = string.Format("name = '{0}'", searchBox.Text);
注意:如果出于某种原因,您更愿意使用 List< Member>
并对其应用过滤器,在加载列表并将其保留在表单成员中后,就像我在上一节中所做的那样,请使用 linq
来过滤数据:
Note: If for any reason you prefer to have a List<Member>
and apply filter on that, after loading and keep the list in a form member like what I did in above sections, use linq
to filter data:
dataGridView1.DataSource = members.Where(x=>x.Name ==searchBox.Text).ToList();
这篇关于使用搜索文本框中的值过滤数据网格视图列表:“对象引用未设置为对象的实例。”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!