none
コンボボックスコントロールにデータセットを関連付けられない RRS feed

  • 質問

  • Visual Studio 2017でVisual Basicを使っています。コンボボックスコントロールに表示するデータを格納するデータセットを作成してソリューションのビルドを行い、コンボボックスコントロールのスマートガクを表示させて[データバインド項目を使用する]にチェックを入れ、[他のデータソース]→[プロジェクトデータソース]→[CategoryDataSet(データセット名)]まで進みましたが、その次に表示されるはずの[CategoryDataTable(データテーブル名)]が表示されず、その代わりに、[CategoryDataSetBindingSource]という表示が出てきてしまい、関連付けができません。

    DataGridViewコントロールでもスマートタグを使ってデータセットを関連付けようとする時にも同様の現象が起きており、関連付けることができません。

    OSはWindows 10 Homeを使っています。

    関連付けることができない原因と対処法をご教示願います。


    2018年10月7日 9:40

すべての返信

  • DataGridView が出てくるということは作っているのは Windows Forms アプリということと理解して、以下のような話でしょうか?

    DataGridView に ComboBox を表示
    http://surferonwww.info/BlogEngine/post/2014/01/23/how-to-show-combobox-column-in-datagridview.aspx

    違うのであれば、どこがどう違うのか具体的に教えてください。

    あと、質問するときは開発環境(.NET のバージョン、DataSet を作るときに DB を使っているならそれは何かなど)を書くようにしてください。前にもお願いしたはずです。

    フォーラムのご利用方法(質問の投稿)について
    https://social.msdn.microsoft.com/Forums/ja-JP/b2074c04-2e91-414d-8e9e-d634be311e31



    • 編集済み SurferOnWww 2018年10月8日 2:05 訂正
    2018年10月8日 2:01
  • 作っているのはWindows Formsアプリです。.NETのバージョンは4.7.03056です。Visual Studio Community 2017のバージョンは15.8.6です。

    データセットはソリューションエクスプローラーのプロジェクトを右クリックしてコンテキストメニューの[追加]→[新しい項目]を選択して、[共通項目]→[データ]を選択→テンプレートから[データセット]を選択して名前を入力して[追加]ボタンをクリックして表示されたデータセットデザイナーにツールボックスから[Data Table]コントロールを選択して、データセットデザイナーにドラッグ&ドロップし、貼り付けた[Data Table]に右クリックして列を追加して作成しました。DBを使ったのではありません。

    ComboBoxはForm上に貼り付けたものです。DataGridViewにComboBoxを表示するわけではありません。DataGridViewにデータセットを関連付けようとする場合にも同様の現象が生じるので原因は同じではないかと思いDataGridViewに言及しただけです。

    2018年10月8日 8:43
  • > データセットはソリューションエクスプローラーの・・・ DBを使ったのではありません。

    それで ComboBox のデータソースに使える DataSet / DadaTable がきちんとできているのでしょうか? そうは思えないのですが・・・

    ウィザードに頼らずコードを書いて DataTable を作成し、それを ComboBox の DataSource に設定してみてください。以下のような感じ。(コードは C# です)

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                ComboBox cb = new ComboBox();
                cb.DataSource = CreateDataTable();
                cb.DisplayMember = "name";
                cb.ValueMember = "id";
                this.Controls.Add(cb);
            }
    
            private DataTable CreateDataTable()
            {
                DataTable table = new DataTable();
                table.Columns.Add(new DataColumn("id", typeof(int)));
                table.Columns.Add(new DataColumn("name", typeof(string)));
    
                for (int i = 0; i < 5; i++)
                {
                    DataRow row = table.NewRow();
                    row["id"] = i;
                    row["name"] = "name-" + i;
                    table.Rows.Add(row);
                }
                return table;
            }
        }
    }

    結果は以下のようになります。それで上手くいかない原因が何かわかりませんか?

    2018年10月8日 9:55
  • ご連絡ありがとうございます。

    コードを書いてDataTableを作成する方法もあるのですね。残念ながら、C#のコードは読めませんので、VBのコードを書いていただけるとありがたいのですが・・・。

    初心者なので、ウィザードに頼るのは大目にみてください。参考書「作って覚えるVisual Basic 2017」(秀和システム)にウィザードを使う方法が書いてあり、その通りにやって不具合が発生しました。自分だけ不具合が発生しているとすれば不安になります。すごく便利な機能なので、利用できないとなればがっかりです。他のみなさんはウィザードを使って作成したDataTableをコンボボックス(あるいはDataGridView)に関連付ける際に不具合は発生していないのでしょうかね。発生しているとすれば、不具合が発生しないようなVBの修正版をリリースしていただけると助かります。

    2018年10月8日 14:43
  • > VBのコードを書いていただけるとありがたいのですが・・・。

    変換サービスなどを使って自力で解決してください。

    Code Converter C# to VB and VB to C# – Telerik
    http://converter.telerik.com/

    > 初心者なので、ウィザードに頼るのは大目にみてください。

    ウィザードは初心者に限らず誰もが有効に利用すべき機能ですが、使い方が間違っていたり中途半端だったりすると逆効果になると思います。

    > 参考書「作って覚えるVisual Basic 2017」(秀和システム)にウィザードを使う方法が書いてあり、その通りにやって不具合が発生しました。

    その本は持ってないので、そういうことを言われても、間違ったことが書いてあるのか、質問者さんのやり方に問題があるのかは分かりません。

    想像ですが、たぶん本には間違ったことは書いてなくて、質問者さんのやり方、

    > データセットはソリューションエクスプローラーの・・・ DBを使ったのではありません

    に問題があるのではないかと思います。(自信度 99.99% ぐらい)

    DBを使ったのではありません」=「DataTable を作っただけで中身がない(私がアップしたコードで言うと for ループの部分がない)」ということではないですか?

    #「初心者なので」と言うのはもうやめませんか? 質問者さんの過去スレッドを見ると 2016 年からこのフォーラムに参加してますよね。


    • 編集済み SurferOnWww 2018年10月9日 0:57 訂正
    2018年10月9日 0:55
  • 想像ですが、たぶん本には間違ったことは書いてなくて、質問者さんのやり方、

    > データセットはソリューションエクスプローラーの・・・ DBを使ったのではありません

    に問題があるのではないかと思います。(自信度 99.99% ぐらい)

    DBを使ったのではありません」=「DataTable を作っただけで中身がない(私がアップしたコードで言うと for ループの部分がない)」ということではないですか?

    とりあえず、手順は提示されてるんだから試すぐらいはしてもいいんじゃないですかね。

    試したところ素直にDataTableが出てきてしまったので、私はこれ以上コメントはできませんが。

    // 試したのはVisual Studio Express 2017 for Windows Desktopですが、Communityでも変わらないところだと思います。

    2018年10月9日 1:26
  • > とりあえず、手順は提示されてるんだから試すぐらいはしてもいいんじゃないですかね。

    私に対してのレスですか? であれば、そういう内容のレスはしていただかなくて結構です。

    質問者さんの問題を解決できるように、あなたは質問者さんに対してきちんと回答してあげていただければと思います。
    2018年10月9日 1:54
  • 横レスが入ったおがけで混乱を招きそうなので、ウィザードを使って DataSet を作った場合でも中身がないとダメということを書いておきます。

    以下の型付 DataSet / DataTable をウィザードで作ります。これだけでは DataSet / DataTable という入れ物ができただけで、中身はありません。

    先にアップしたコードを、上記の DataSet / DataTable を使って、同じ結果になるように書き換えると以下の通りになります。for ループで中身を入れてます。実行結果は先のレスの画像と同じで、期待通り ComboBox に中身が表示されます。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                ComboBox cb = new ComboBox();
    
                //cb.DataSource = CreateDataTable();
    
                DataSet1 dataset = new DataSet1();
                for (int i = 0; i < 5; i++)
                {
                    dataset.DataTable1.AddDataTable1Row(i, "name-" + i);
                }
    
                cb.DataSource = dataset.DataTable1;
                cb.DisplayMember = "name";
                cb.ValueMember = "id";
                this.Controls.Add(cb);
            }
    
            //private DataTable CreateDataTable()
            //{
            //    DataTable table = new DataTable();
            //    table.Columns.Add(new DataColumn("id", typeof(int)));
            //    table.Columns.Add(new DataColumn("name", typeof(string)));
    
            //    for (int i = 0; i < 5; i++)
            //    {
            //        DataRow row = table.NewRow();
            //        row["id"] = i;
            //        row["name"] = "name-" + i;
            //        table.Rows.Add(row);
            //    }
            //    return table;
            //}
        }


    • 編集済み SurferOnWww 2018年10月9日 2:25 訂正
    2018年10月9日 2:24
  • ウィザードに関した質問ですので、私はウィザードに関して書きますね。ご質問文に疑問も感じましたので。

    [他のデータソース]→[プロジェクトデータソース]→[CategoryDataSet(データセット名)]まで進みましたが、その次に表示されるはずの[CategoryDataTable(データテーブル名)]が表示されず、その代わりに、[CategoryDataSetBindingSource]という表示が出てきてしまい

    これは通常ではありえないことです。なぜならBindingSourceはDataSetに属するものではないからです。BindingSourceはDataSetやDataTableをラップするもので、ウィザードでどちらかを選ぶと自動的に生成されます。ラップするものですから、当然、DataSetの下には表示されず、下図のようにDataSetと並列に表示されます。

    なお、ComboBoxやDataGridViewにバインドするのはBindingSourceでかまいません。というより、推薦されており、ウィザードで作成するとDataTableをバインド先に選んでもそれをラップするBindingSourceが作成され、BindingSourceにバインドされます。
    ちなみにBindingSourceがバインドされた状態で、表示メンバーや値メンバーは選択できますか? 選択できないのであれば、DataTableを選んでBindingSourceが生成されているのではなく、DataSetを選んでBindingSourceが生成されてしまっています。

    以上で、BindingSourceとDataTableの関係が理解できましたでしょうか?

    おそらく、最初に引用したご質問内容の、

    その次に表示されるはずの[CategoryDataTable(データテーブル名)]が表示されず、その代わりに、[CategoryDataSetBindingSource]という表示が出てきてしまい、関連付けができません。

    が、正確な表現になっていない気がします。もし、本当にそのようになっているのであれば、DataTableの名前が「CategoryDataSetBindingSource」になっているとしか思えないのですが・・・・・でもそんなことはないですよね・・・
    そうでないとすれば、Visual Studioがやっかいなことになっていると思うので、ちゃんと修正しないとこの先まずいことが起きるかもしれません。
    逆にどうやったらVB坂東太郎さんが書かれているようになるのか、私の方では再現できませんでした。
    もし、データソースを選択する画面が貼り付けられれば、お願いします。


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 編集済み trapemiyaModerator 2018年10月9日 7:25 敬称が抜けていました。コピペしてうっかりしました。すみません。
    2018年10月9日 5:27
    モデレータ
  • 「プロジェクトデータソース」で、DataSet1を選べばDataSet1BindingSourceが作成されますしDataTable1を選べばDataTable1BindingSourceが作成されます。別に特異なことでもなく。

    もちろん、DataSetをデータソースにしたらそのままでは意味のあるバインディングが行えないので、DataSet1BindingSourceのDataMemberプロパティでDataTable1を設定する必要がありますが。


    • 編集済み Hongliang 2018年10月9日 5:46 画像貼り損ね
    2018年10月9日 5:45