none
DataGridViewについて(初心者です) RRS feed

  • 質問

  • いつも大変お世話になっています。

    Win8.1  VS2010 C#で開発しています。

    C#は全くの初心者です。

    初歩的な質問でお時間をとらせてしまって申し訳ありませんが、よろしくお願いいたします。

    Form1に、DataGridViewとbindingNavigatorを張り付け、

    情報ファイルを読み込むたびに、DataGridViewの構成を新たに作り直し、

    CSVファイルを読み込むたびに、データをクリアして1行目からセットしなおす処理を行いたいと思っています。

    簡単なテストプログラムを作ってみようと試みたのですが、つまずいてばかりです。

    データは、BindingSourceにセットして、DataGridViewとbindingNavigatorに関連付けています。

    まず、BindingSourceにCSVから読み込んだデータをAddする記述方法がわかりません。

    情報ファイルの内容によって、列数やプロパティはその都度変わります。

    下記にソースを添付させていただきました。

    最後の関数、toolStripDRead_Click()で、

    (dcnt == 0)の場合は、”山田 花子”と<30>を

    (dcnt == 1)の場合は、”大阪府”と<12345>と<null>をAddするには

    どのようにコーディングすればよいのでしょうか?

    ご指導、よろしくお願いいたします。

    ---------------------------------------------------------------------------------

            BindingSource dataSource=null;

            public Form1()
             {
                 InitializeComponent();
             }

            private static int fcnt = 0;
            private static int dcnt = 0;

            private void toolStripFRead_Click(object sender, EventArgs e)
            {
                 if(dataSource!=null)    dataSource.Dispose();
                 dataSource = new BindingSource();

                if (dataGridView1.Columns.Count > 0)
                 {
                     int loop = dataGridView1.Columns.Count;
                     for (int i = 0; i < loop; i++)
                     {
                         dataGridView1.Columns.RemoveAt(0);
                     }
                 }

                 if (fcnt == 0)
                 {
                     DataGridViewColumn c = new DataGridViewTextBoxColumn();
                     c.DataPropertyName = "Name";
                     c.HeaderText = "名前";
                     dataGridView1.Columns.Add(c);

                    c = new DataGridViewTextBoxColumn();
                     c.DataPropertyName = "Age";
                     c.HeaderText = "年齢";
                     dataGridView1.Columns.Add(c);
                     fcnt++;
                 }
                 else
                 {
                     DataGridViewColumn c = new DataGridViewTextBoxColumn();
                     c.DataPropertyName = "add";
                     c.HeaderText = "住所";
                     dataGridView1.Columns.Add(c);

                    c = new DataGridViewTextBoxColumn();
                     c.DataPropertyName = "id";
                     c.HeaderText = "ID";
                     dataGridView1.Columns.Add(c);

                    DataGridViewButtonColumn d = new DataGridViewButtonColumn();
                     d.HeaderText = "ボタン";
                     d.Text = "Push Me!";
                     d.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                     dataGridView1.Columns.Add(d);
                     d.UseColumnTextForButtonValue = true;

                }
                 bindingNavigator1.BindingSource = dataSource;
                 dataGridView1.DataSource = dataSource;
             }

            private void toolStripDRead_Click(object sender, EventArgs e)
            {
                 if (dcnt == 0)
                 {
                    dataSource.Add();
                    dataSource.Add();
                    dataSource.Add();

                    dcnt++;
                 }
                 else
                 {
                 }
                 bindingNavigator1.BindingSource = dataSource;
                 dataGridView1.DataSource = dataSource;

            }

    2014年8月20日 4:41

回答

  • こんな
    #DataGridViewのDataSourceの与え方が変わってるからAutoGenerateColumnsがいらなくなってるのね

    private void toolStripDRead_Click(object sender, EventArgs e)
    {
        DataTable table = new DataTable();
        if (dcnt == 0)
        {
            table.Columns.Add("Name", typeof(string));
            table.Columns.Add("Age", typeof(int));
    
            DataRow row;
            row=table.NewRow();
                    
            row["Name"] = "山田 花子";
            row["Age"] = 30;
            table.Rows.Add(row);
    
            row = table.NewRow();
            row["Name"] = "name2";
            row["Age"] = 50;
            table.Rows.Add(row);
    
            table.Rows.Add("名前3", 18);
    
            this.dataSource.DataSource = table;
            dcnt++;
        }
        else
        {
            table.Columns.Add("add", typeof(string));
            table.Columns.Add("id", typeof(int));
    
            DataColumn clm;
            clm = table.Columns.Add("button", typeof(int));//3列目のボタン列にもデータを入れる必要があるのなら。
            clm.AllowDBNull = true;//3列目のボタン列にnullを入れる必要があるならnull許可
            clm.DefaultValue = null;
    
            table.Rows.Add("大阪府", 12345, null);
            table.Rows.Add("東京都", 999, null);
        }
     
        this.dataSource.DataSource = table; //BindingSourceが読み書きするデータ集合としてDataTableを設定してやる
        this.dataSource.DataMember = "";//DataSourceにDataTableを設定するなら空にする
    
        bindingNavigator1.BindingSource = dataSource;//カレント位置を制御するデータとしてBindingSourceを設定してやる
        dataGridView1.DataSource = dataSource;//DataGridViewで表示するデータとしてBindingNavigatorを設定してやる。
    }

    DataGridViewのDataGridViewColumnは、DataGridViewのDataSourceに設定されているデータ集合からDataPropertyNameで設定されているデータ名を探して表示や入力を行います。
    ならば、DataPropertyNameで見つけられるデータというのはどこにあるのかということになります。
    DataGridViewのDataSourrceにBindingNavigatorを設定し、そのBindingNavigatorにBindingSourceが設定されていますよね。
    こうやって流れを追いかけていくとBindingSourceのDataSourceに設定したデータ集合にDataPropertyNameで見つけられる項目がないといけないということになります。しかし、提示されているコードではそのような項目はどこにもありません。

    では、BindingSourceのDataSourceに入れる必要があるデータ集合は何なのかです。
    元になるデータの項目が固定されている場合なら、DataPropertyNameと同じ名前のプロパティを持っているクラスの集合を入れてやればよくなります。
    ですが、今回の質問では項目が固定されていませんから、項目数を変動させることができるクラスを与えてやる必要があることがわかります。そういった用途にはDataTableが使えます。DataGridViewに列を追加したのと同じようなやり方で的にDataTableの列を追加してやり、その列名をDataPropertyNameと一致させれば実現できるということです。

    情報ファイルの構造が不明な場合は都度DataTableを作る必要がありますが、既知の種類しかないのであれば、あらかじめ型付DataSetを用意することで、いちいちコードでDataTableを作らなくて済みますよ。

    #最初の質問文を消してしまったのはよくないけれど、その後の不手際は不慣れだから仕方がない部分が多いと思うけどなぁ


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2014年8月20日 14:48 誤字脱字の修正
    • 回答としてマーク kizakura_ui 2014年8月21日 0:01
    2014年8月20日 9:59

すべての返信

  • 以前の別スレッドでの質問の続きですか?

    http://social.msdn.microsoft.com/Forums/ja-JP/071613ca-d8c6-4cda-81b1-1820734d0b14/datagridview?forum=vcexpressja

    であれば、そこでいろいろお願いされていると思いますが、聞いていただけないのでしょうか?

    2014年8月20日 5:22
  • そうです。

    間違えてC++のフォーラムで質問してしまったので、

    C#のフォーラムに再度投稿させていただきました。

    また間違っていますか?

    2014年8月20日 6:03
  • 前のスレッドのレスをよく読んででください。特に Azulean さんの言われている事。

    あなたが最初に書いた質問を書き換えた(消した)ことによって、先のスレッド全体が訳の分からないノイズを増やしただけと言う結果になってしまったということを自覚してください。

    ここはあなた専用の Q&A サイトではありません。

    2014年8月20日 6:19
  • 申し訳ありませんでした。

    これ以上、無駄なお時間をとらせては申し訳ないと思い、消去させていただいたのですが、

    返ってご迷惑をおかけしてしまったようです。

    投稿サイトを間違えた場合はどうすればよかったのでしょうか?

    ルールのようなものもわからず、本当にすみません。

    2014年8月20日 6:29
  • 再度、申し訳ありませんでした。

    今、元の質問欄を見せていただいて、さらにご意見を書き込んでいただいていることを知りました。

    反省しきりです。

    ご迷惑をおかけいたしました。

    2014年8月20日 6:31
  • こんな
    #DataGridViewのDataSourceの与え方が変わってるからAutoGenerateColumnsがいらなくなってるのね

    private void toolStripDRead_Click(object sender, EventArgs e)
    {
        DataTable table = new DataTable();
        if (dcnt == 0)
        {
            table.Columns.Add("Name", typeof(string));
            table.Columns.Add("Age", typeof(int));
    
            DataRow row;
            row=table.NewRow();
                    
            row["Name"] = "山田 花子";
            row["Age"] = 30;
            table.Rows.Add(row);
    
            row = table.NewRow();
            row["Name"] = "name2";
            row["Age"] = 50;
            table.Rows.Add(row);
    
            table.Rows.Add("名前3", 18);
    
            this.dataSource.DataSource = table;
            dcnt++;
        }
        else
        {
            table.Columns.Add("add", typeof(string));
            table.Columns.Add("id", typeof(int));
    
            DataColumn clm;
            clm = table.Columns.Add("button", typeof(int));//3列目のボタン列にもデータを入れる必要があるのなら。
            clm.AllowDBNull = true;//3列目のボタン列にnullを入れる必要があるならnull許可
            clm.DefaultValue = null;
    
            table.Rows.Add("大阪府", 12345, null);
            table.Rows.Add("東京都", 999, null);
        }
     
        this.dataSource.DataSource = table; //BindingSourceが読み書きするデータ集合としてDataTableを設定してやる
        this.dataSource.DataMember = "";//DataSourceにDataTableを設定するなら空にする
    
        bindingNavigator1.BindingSource = dataSource;//カレント位置を制御するデータとしてBindingSourceを設定してやる
        dataGridView1.DataSource = dataSource;//DataGridViewで表示するデータとしてBindingNavigatorを設定してやる。
    }

    DataGridViewのDataGridViewColumnは、DataGridViewのDataSourceに設定されているデータ集合からDataPropertyNameで設定されているデータ名を探して表示や入力を行います。
    ならば、DataPropertyNameで見つけられるデータというのはどこにあるのかということになります。
    DataGridViewのDataSourrceにBindingNavigatorを設定し、そのBindingNavigatorにBindingSourceが設定されていますよね。
    こうやって流れを追いかけていくとBindingSourceのDataSourceに設定したデータ集合にDataPropertyNameで見つけられる項目がないといけないということになります。しかし、提示されているコードではそのような項目はどこにもありません。

    では、BindingSourceのDataSourceに入れる必要があるデータ集合は何なのかです。
    元になるデータの項目が固定されている場合なら、DataPropertyNameと同じ名前のプロパティを持っているクラスの集合を入れてやればよくなります。
    ですが、今回の質問では項目が固定されていませんから、項目数を変動させることができるクラスを与えてやる必要があることがわかります。そういった用途にはDataTableが使えます。DataGridViewに列を追加したのと同じようなやり方で的にDataTableの列を追加してやり、その列名をDataPropertyNameと一致させれば実現できるということです。

    情報ファイルの構造が不明な場合は都度DataTableを作る必要がありますが、既知の種類しかないのであれば、あらかじめ型付DataSetを用意することで、いちいちコードでDataTableを作らなくて済みますよ。

    #最初の質問文を消してしまったのはよくないけれど、その後の不手際は不慣れだから仕方がない部分が多いと思うけどなぁ


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2014年8月20日 14:48 誤字脱字の修正
    • 回答としてマーク kizakura_ui 2014年8月21日 0:01
    2014年8月20日 9:59
  • > 投稿サイトを間違えた場合はどうすればよかったのでしょうか?

    投稿先フォーラムを間違えた場合、基本的に管理者の方で適切なフォーラムに移動するので、質問者がスレッドを立て直す必要はありません。スレッドを継続するようお願いします。

    またすでに他の方から指摘されてますが、最初の質問内容は極力編集されないようお願いします。他の方が後から読んだとき判らなくなります。

    先ほどまでは元のスレに戻って質疑を再開された方がいいかとも思ったのですが、gekka さんから返信ありましたので、こちらに移動された方がいいように思います。


    MSDNフォーラムのヘルプは以下ご覧ください http://social.technet.microsoft.com/wiki/contents/articles/7359.forums-help-faq.aspx

    2014年8月20日 11:08
    モデレータ
  • フォーラムにご参加の皆様には、ご不快な思いやご面倒をおかけしたにもかかわらず、

    このように詳しいご指導をいただき感謝に堪えません。

    また、優しいコメントもありがとうございました。

    ほかの方の叱責、”ここはあなた専用の Q&A サイトではありません。”で、

    自分が多大なご迷惑をおかけしたことに改めて気づかされました。

    添付してくださった、”private void toolStripDRead_Click(object sender, EventArgs e)”を

    使って起動したところ、はじめは思い通りの結果が出ませんでしたが、

    この関数以外の部分を何ヶ所か修正した結果、うまく動作してくれました。

    詳しいコメントと解説のお蔭で、どう修正したらよいかもすぐにわかりました。

    私が疑問に思っていることが見えていらっしゃるような的を射たわかりやすい解説で、

    頭の中がすっきりしています。

    さらに、教えていただいたことがきちんと身につくように掘り下げてみます。

    ほんとうにありがとうございました。

    今後ともご指導よろしくお願いいたします。


    kizakura_ui

    2014年8月21日 0:26
  • ご指導ありがとうございます。

    最初に投稿したスレッドを消去してしまった後に、いろいろご意見をお寄せいただいていたことに

    気づいていなかったことも大変反省しております。

    ”自動更新”や”アラート”の設定ができることも知らなかったので、

    さっそく行いました。

    今後とも、よろしくお願いいたします。


    kizakura_ui

    2014年8月21日 0:29