検索テキストボックスの値を使用して、データグリッドビューリストをフィルタ処理します: 'オブジェクト参照がオブジェクトのインスタンスに設定されていません。

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 members = new List();

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 に変更しようとしました。 DataTable の前に List/Member を使用してキャストしてみましたが、うまくいきません。

これに対する最良のアプローチは何ですか?

編集する

これが私のSQL selectからのデータの各行をリストに追加する方法です。

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
    });
}
1
@RezaAghaeiデータグリッドへの入力方法についての質問を更新しました。
追加された 著者 J.Do,
@RezaAghaeiデータグリッドへの入力方法についての質問を更新しました。
追加された 著者 J.Do,
@RezaAghaeiこれを機能させるには、グリッドにデータを追加する方法を完全に変更する必要がありますか?
追加された 著者 J.Do,
@RezaAghaeiこれを機能させるには、グリッドにデータを追加する方法を完全に変更する必要がありますか?
追加された 著者 J.Do,
データベースに行を追加してデータソースを使用しなかったため、 DataSource はnullです。
追加された 著者 Reza Aghaei,
その答えには、 DataTable または List を使用して DataGridView にデータを表示し、データをフィルタするための解決策が含まれています。
追加された 著者 Reza Aghaei,
その答えには、 DataTable または List を使用して DataGridView にデータを表示し、データをフィルタするための解決策が含まれています。
追加された 著者 Reza Aghaei,
データを DataTable にロードし、それを DataGridView DataSource として設定するだけです。それからフィルタリングはあなたがやろうとしているのと同じ方法で行うことができます。
追加された 著者 Reza Aghaei,
データを DataTable にロードし、それを DataGridView DataSource として設定するだけです。それからフィルタリングはあなたがやろうとしているのと同じ方法で行うことができます。
追加された 著者 Reza Aghaei,
データベースに行を追加してデータソースを使用しなかったため、 DataSource はnullです。
追加された 著者 Reza Aghaei,
memberGrid DataSource は何ですか。 DataGridView のデータソースを設定するコードを見せてください。
追加された 著者 Reza Aghaei,
memberGrid DataSource は何ですか。 DataGridView のデータソースを設定するコードを見せてください。
追加された 著者 Reza Aghaei,
DataGridViewのデータソースはおそらく List です。 DataTable ではありません。そのため、DataTableとしての memberGrid.DataSource はnullです。
追加された 著者 Reza Aghaei,
DataGridViewのデータソースはおそらく List です。 DataTable ではありません。そのため、DataTableとしての memberGrid.DataSource はnullです。
追加された 著者 Reza Aghaei,
stackoverflow.com/q/4166403/656243 を正確に複製したもの
追加された 著者 Lynn Crumbling,
すべてのコードを利用できるわけではありませんが、投稿した内容に基づいて、 List DataGrid のデータソースとして設定していると思います。後者はnullとして評価される DataTable としてそれを扱おうとしています、そしてそれがあなたが 'オブジェクト参照がオブジェクトのインスタンスに設定されていない。 "例外を得る理由です。 DataGridをDataTableにバインドすると、問題は解決します。
追加された 著者 Dipen Shah,
すべてのコードを利用できるわけではありませんが、投稿した内容に基づいて、 List DataGrid のデータソースとして設定していると思います。後者はnullとして評価される DataTable としてそれを扱おうとしています、そしてそれがあなたが 'オブジェクト参照がオブジェクトのインスタンスに設定されていない。 "例外を得る理由です。 DataGridをDataTableにバインドすると、問題は解決します。
追加された 著者 Dipen Shah,

4 答え

DataGridView DataSource を設定していないためnullであるため、このステートメントで使用したときに例外が発生しました。 .DefaultView ...

DataGridView に行を1つずつ追加する代わりに、データをその DataSource に割り当てます。次に、使用しているデータ構造に応じて、データをフィルタ処理できます。

以下の解決策のいずれかを使用できます。

  • As an option, to fix the problem, you can load data into a DataTable and set it as DataSource of the DataGridView. Then the filtering can be done the same way that you are trying to do.

  • Also if for any reason you prefer to have a List and apply filter on that, after loading data and converting to a List, keep the list in a form member field like List members; then for filtering using linq:

    dataGridView1.DataSource = members.Where(x=>x.Name ==searchBox.Text).ToList();
    

詳細については、記事の以下のセクションを読んでください。

NullReferenceExceptionが発生する理由

次のコード行は、 DataSource がnullの場合、または DataSource DataTable でない場合、 NullReferenceException をスローします。

(memberGrid.DataSource as DataTable).DefaultView.RowFilter = ...

あなたの場合、あなたは行を追加することによってデータベースをいっぱいにしていて、そのデータソースを使わなかったので、 DataSource はnullで、上記のコードは例外を投げます。

NullReferenceException をデバッグする方法の詳細については、 NullReferenceExceptionとは何ですか。修正しますか?

データを読み込む

あなたは言及しました:

このようにして、私のSQL selectからデータの各行をリストに追加します。

  members.Add(新しいメンバー{
      id = Convert.ToInt32(reader ["id"])、
      name = reader ["name"]。ToString()、
      ...
 

It seems you are using a SQL query and a SqlDataReader. Then you don't need to use a List, 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;
}

Note: If for any reason you are interested to keep working with List, refactor your code to return a List in GetData:

public List 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("id"),
        name = r.Field("name"),
        age = r.Field("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[]
      ...

When you load data into a DataTable (or even in a List) 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 <のデータソースとして設定します。/code>:

DataTable dt;
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    dt = LoadData();
    dataGridView1.DataSource = dt;
}

Note: If for any reason you preferred returning a List from GetData, the code will be:

List members;
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    members = LoadData();
    dataGridView1.DataSource = members;
}

データをフィルタ

それからデータをフィルタするためには、 dt.DefaultView.RowFilter を使うだけです。

dt.DefaultView.RowFilter = string.Format("name = '{0}'", searchBox.Text);

Note: If for any reason you prefer to have a List 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();
4
追加された

DataGridView DataSource を設定していないためnullであるため、このステートメントで使用したときに例外が発生しました。 .DefaultView ...

DataGridView に行を1つずつ追加する代わりに、データをその DataSource に割り当てます。次に、使用しているデータ構造に応じて、データをフィルタ処理できます。

以下の解決策のいずれかを使用できます。

  • As an option, to fix the problem, you can load data into a DataTable and set it as DataSource of the DataGridView. Then the filtering can be done the same way that you are trying to do.

  • Also if for any reason you prefer to have a List and apply filter on that, after loading data and converting to a List, keep the list in a form member field like List members; then for filtering using linq:

    dataGridView1.DataSource = members.Where(x=>x.Name ==searchBox.Text).ToList();
    

詳細については、記事の以下のセクションを読んでください。

NullReferenceExceptionが発生する理由

次のコード行は、 DataSource がnullの場合、または DataSource DataTable でない場合、 NullReferenceException をスローします。

(memberGrid.DataSource as DataTable).DefaultView.RowFilter = ...

あなたの場合、あなたは行を追加することによってデータベースをいっぱいにしていて、そのデータソースを使わなかったので、 DataSource はnullで、上記のコードは例外を投げます。

NullReferenceException をデバッグする方法の詳細については、 NullReferenceExceptionとは何ですか。修正しますか?

データを読み込む

あなたは言及しました:

このようにして、私のSQL selectからデータの各行をリストに追加します。

  members.Add(新しいメンバー{
      id = Convert.ToInt32(reader ["id"])、
      name = reader ["name"]。ToString()、
      ...
 

It seems you are using a SQL query and a SqlDataReader. Then you don't need to use a List, 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;
}

Note: If for any reason you are interested to keep working with List, refactor your code to return a List in GetData:

public List 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("id"),
        name = r.Field("name"),
        age = r.Field("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[]
      ...

When you load data into a DataTable (or even in a List) 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 <のデータソースとして設定します。/code>:

DataTable dt;
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    dt = LoadData();
    dataGridView1.DataSource = dt;
}

Note: If for any reason you preferred returning a List from GetData, the code will be:

List members;
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    members = LoadData();
    dataGridView1.DataSource = members;
}

データをフィルタ

それからデータをフィルタするためには、 dt.DefaultView.RowFilter を使うだけです。

dt.DefaultView.RowFilter = string.Format("name = '{0}'", searchBox.Text);

Note: If for any reason you prefer to have a List 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();
4
追加された

Reza Aghaeiは、問題を解決する方法を説明しましたが、将来的に誰かがこれらの状況を処理するためのもう1つの方法を必要とする場合に備えて、私はそれをどのように行うかです。

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

それが起こるかもしれない2つの理由があります。

  • You DataSource is not assigned so it is null
  • You assigned object with other type than DataTable and then you try to cast it "back" to DataTable so it returns null

完璧なフローでは、常にデータをデータソースにバインドし、それを通して操作します。 これが私のデータグリッドビューでのやり方です。

  • まず、DataTableに直接データを読み込もうとしています

So if you are loading it from SQL just use DataAdapter and fill DataTable

using(SqlConnetion....)
{
    con.Open();
    using(SqlDataAdapter da ....)
    {
        DataTable dt = new DataTable();
        da.Fill(dt);

        dataGridView.DataSource = dt;

        //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.
    }
}

If loading data directly do DataTable is for some reason hard for you (need to create datatable yourself and populate it with foreach but too many columns or something like that) or you want to manipulate data inside your code but not in DataTable you can use List

単純にオブジェクトを作成する

public class Car
{
    public string Model { get; set; }
    public Color Color { get; set; }
    public string LicencePlate { get; set; }
    public doube HP { get; set; }

    public Car()
    {
    }
}

then let's say we need to load cars from jsonString we do List myCars = JsonConverter.Deserialize>(stringFromWebForExample);

そして今、私たちは操作できるリストを持っていますが、それをdatagridviewに入れる必要があります。 dataGridView.DataSource = myCars でもできますが、 DataTable List よりも機能的に機能します。このコードを使って、そのリストをデータテーブルに変換します。

public static DataTable ConvertToDataTable(this IList data)
{
    PropertyDescriptorCollection properties =
       TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    foreach (PropertyDescriptor prop in properties)
        table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
    foreach (T item in data)
    {
        DataRow row = table.NewRow();
        foreach (PropertyDescriptor prop in properties)
            row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
        table.Rows.Add(row);
    }
    return table;
}

and just call it dataGridView.DataSource = myCars.ConvertToDataTable();

So that are two practical ways of handing data and displaying it in DataGridView

4
追加された
また、OPが要求したような場合には、最初からデータを DataTable に読み込むことができるので、データをリストに変換してからフィルタリングする必要はありませんジェネリックリストをデータテーブルに変換する
追加された 著者 Reza Aghaei,
ユーザーは List のフィルタリングにlinqを使用できますが、文字列フィルターを使用してフィルタリングを実行したい場合は、次のように System.Linq.Dynamic を使用することをお勧めします。 こちらをご覧ください。
追加された 著者 Reza Aghaei,

Reza Aghaeiは、問題を解決する方法を説明しましたが、将来的に誰かがこれらの状況を処理するためのもう1つの方法を必要とする場合に備えて、私はそれをどのように行うかです。

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

それが起こるかもしれない2つの理由があります。

  • You DataSource is not assigned so it is null
  • You assigned object with other type than DataTable and then you try to cast it "back" to DataTable so it returns null

完璧なフローでは、常にデータをデータソースにバインドし、それを通して操作します。 これが私のデータグリッドビューでのやり方です。

  • まず、DataTableに直接データを読み込もうとしています

So if you are loading it from SQL just use DataAdapter and fill DataTable

using(SqlConnetion....)
{
    con.Open();
    using(SqlDataAdapter da ....)
    {
        DataTable dt = new DataTable();
        da.Fill(dt);

        dataGridView.DataSource = dt;

        //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.
    }
}

If loading data directly do DataTable is for some reason hard for you (need to create datatable yourself and populate it with foreach but too many columns or something like that) or you want to manipulate data inside your code but not in DataTable you can use List

単純にオブジェクトを作成する

public class Car
{
    public string Model { get; set; }
    public Color Color { get; set; }
    public string LicencePlate { get; set; }
    public doube HP { get; set; }

    public Car()
    {
    }
}

then let's say we need to load cars from jsonString we do List myCars = JsonConverter.Deserialize>(stringFromWebForExample);

そして今、私たちは操作できるリストを持っていますが、それをdatagridviewに入れる必要があります。 dataGridView.DataSource = myCars でもできますが、 DataTable List よりも機能的に機能します。このコードを使って、そのリストをデータテーブルに変換します。

public static DataTable ConvertToDataTable(this IList data)
{
    PropertyDescriptorCollection properties =
       TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    foreach (PropertyDescriptor prop in properties)
        table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
    foreach (T item in data)
    {
        DataRow row = table.NewRow();
        foreach (PropertyDescriptor prop in properties)
            row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
        table.Rows.Add(row);
    }
    return table;
}

and just call it dataGridView.DataSource = myCars.ConvertToDataTable();

So that are two practical ways of handing data and displaying it in DataGridView

4
追加された
また、OPが要求したような場合には、最初からデータを DataTable に読み込むことができるので、データをリストに変換してからフィルタリングする必要はありませんジェネリックリストをデータテーブルに変換する
追加された 著者 Reza Aghaei,
ユーザーは List のフィルタリングにlinqを使用できますが、文字列フィルターを使用してフィルタリングを実行したい場合は、次のように System.Linq.Dynamic を使用することをお勧めします。 こちらをご覧ください。
追加された 著者 Reza Aghaei,