C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: DataGridViewComboBoxColumnのデータ


(過去ログ 65 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■37486 / inTopicNo.1)  DataGridViewComboBoxColumnのデータ
  
□投稿者/ mori (1回)-(2009/06/23(Tue) 22:11:19)

分類:[C#] 

DataGridViewComboBoxColumnのデータが更新できないのですが、

「年」選択ComboBoxと「データ」表示用DataGridViewで、年ごとの一覧と商品の選択をするものなのですが、
初期表示では2009年のデータが一覧表示され、一つのカラムにDataGridViewComboBoxColumnで商品データが選択できるようにしています。
ComboBoxで2008年を選択するとDataGridViewComboBoxColumnの中身を入れ替えているはずなのに20098年のデータが入ったまま表示されエラーとなります。

using (DataTable dt = new DataTable())
{
da.Fill(dt);
Column1.Items.Clear();
foreach (DataRow dr in dt.Rows)
{
Column1.Items.Add(dr[0].ToString());
}
}
DataTableにはSQLより「年」の商品リストを取得しています。
初期表示した時には同じロジックでデータが入るのに、なぜ入れ替えしようとするとうまくいかないのかがわかりません。
初期のデータ追加と次からのデータ入れ替えで何が違うのでしょうか?
どうすればデータが更新できるのでしょうか?
引用返信 編集キー/
■37502 / inTopicNo.2)  Re[1]: DataGridViewComboBoxColumnのデータ
□投稿者/ ぱぱいやん (46回)-(2009/06/24(Wed) 09:25:46)
ぱぱいやん さんの Web サイト
No37486 (mori さん) に返信
> DataGridViewComboBoxColumnのデータが更新できないのですが、
>
> 「年」選択ComboBoxと「データ」表示用DataGridViewで、年ごとの一覧と商品の選択をするものなのですが、
> 初期表示では2009年のデータが一覧表示され、一つのカラムにDataGridViewComboBoxColumnで商品データが選択できるようにしています。
> ComboBoxで2008年を選択するとDataGridViewComboBoxColumnの中身を入れ替えているはずなのに20098年のデータが入ったまま表示されエラーとなります。
>
> using (DataTable dt = new DataTable())
> {
> da.Fill(dt);
> Column1.Items.Clear();
> foreach (DataRow dr in dt.Rows)
> {
> Column1.Items.Add(dr[0].ToString());
> }
> }
> DataTableにはSQLより「年」の商品リストを取得しています。
> 初期表示した時には同じロジックでデータが入るのに、なぜ入れ替えしようとするとうまくいかないのかがわかりません。
> 初期のデータ追加と次からのデータ入れ替えで何が違うのでしょうか?
> どうすればデータが更新できるのでしょうか?

エラーの内容を提示してください。
それと、エラーが発生する前に、dt にセットされた値がどのようになっているのか確認してみてください。
引用返信 編集キー/
■37545 / inTopicNo.3)  Re[2]: DataGridViewComboBoxColumnのデータ
□投稿者/ mori (2回)-(2009/06/24(Wed) 19:18:03)
エラーは、「DataGridViewComboBoxCellの値が有効ではありません。」と出ます。
デバッグで追いかけてみても、DataTableとDataGridViewComboBoxColumnの値は正常に取得更新出来ています。
が、一覧に表示されたとき、一覧データは2008年データなのに、DataGridViewComboBoxColumnの値が2009年のままなのでエラーが出ます。
なぜ更新されないのかがわかりません。

引用返信 編集キー/
■37587 / inTopicNo.4)  Re[3]: DataGridViewComboBoxColumnのデータ
□投稿者/ カドルドエグ (90回)-(2009/06/25(Thu) 14:00:56)
No37545 (mori さん) に返信
今の文面だけで判断するに、
更新できないのはおそらくそのエラー(値が有効ではありませんエラー)が
原因ではないかと思っています。

なので、データ取得と切替に重点を置いて
VS2005 C#でサンプルを書いてみました。
汚さについてはご了承ください。。

※画面:DataGridView×1(DataGridViewComboBoxColumnが既に1つ追加された状態)
    ComboBox×1

詳しい仕様がわからないまま書いてるのでどこかしら勘違いはあるかもしれません。
とりあえず※の条件下だと↓の処理でConboBoxでの切替時にエラーは出ませんでした。
---------------------------------------------------------------------------
 public partial class Form1 : Form
    {
        // DataGridViewComboBoxColumn用テーブル
        private DataTable table = new DataTable();

        // DataGridView本体用テーブル
        private DataTable table2 = new DataTable();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            /*テスト用データの設定*/
            table.Columns.Add("C1");
            table.Columns.Add("C2");
            table.Columns.Add("C3");

            table2.Columns.Add("Cあ");
            table2.Columns.Add("Cい");
            table2.Columns.Add("Cう");
            table2.Columns.Add("Cえ");

            GetData();
            GetData2(false);
            /**********************/

            // Column1 = DataGridViewにくっついているDataGridViewComboBoxColumn
            foreach (DataRow row in table.Rows)
            {
                Column1.Items.Add(row[1].ToString());
            }
            Column1.DataPropertyName = "Cい";
            dgv.DataSource = table2;

            // データ切替用コンボボックス(年にあたる)の設定
            SetCombo();
        }

        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex < 0)
            {
                return;
            }
            if (comboBox1.SelectedValue.ToString() == "b")
            {
                GetData2(true);

                // 質問者さんが行った方法を踏襲
                GetData4(); // ←データを取得:da.Fill(dt)にあたる処理        
                Column1.Items.Clear();
                foreach (DataRow row in table.Rows)
                {
                    Column1.Items.Add(row[1].ToString());
                }

            }
            else
            {
                GetData2(false);
                GetData();
                Column1.Items.Clear();
                foreach (DataRow row in table.Rows)
                {
                    Column1.Items.Add(row[1].ToString());
                }
            }
            dgv.DataSource = table2;
        }

        /*↓サンプル用の仕込み↓*/
        private void SetCombo()
        {
            Pattern[] source = new Pattern[] { new Pattern("こっち", "a"), new Pattern("あっち", "b") };
            comboBox1.DataSource = source;
            comboBox1.DisplayMember = "Kanji";
            comboBox1.ValueMember = "ValueStr";
        }

        private struct Pattern
        {
            private string kanji;
            private string valusStr;
            public Pattern(string p_kanji, string p_value)
            {
                kanji = p_kanji;
                valusStr = p_value;
            }

            public string ValueStr
            {
                get { return valusStr; }
            }

            public string Kanji
            {
                get { return kanji; }
            }

        }

        private void GetData()
        {
            table.Rows.Add("aaaa", "1", "gerger");
            table.Rows.Add("bbbb", "2", "dfgver");
            table.Rows.Add("cccc", "3", "ofdhjoi");
            table.Rows.Add("dddd", "4", "fbgdjog");
        }

        private void GetData4()
        {
            if (table.Rows.Count > 0) table.Clear();
            table.Rows.Add("eeee", "1", "gerger");
            table.Rows.Add("ffff", "2", "dfgver");
            table.Rows.Add("ggggg", "3", "ofdhjoi");
            table.Rows.Add("hhhh", "4", "fbgdjog");

        }

        private void GetData2(bool getB)
        {
            if (table2.Rows.Count > 0) table2.Clear();
            if (getB)
            {
                table2.Rows.Add("LLL", "4", "gerger", "b");
                table2.Rows.Add("FFF", "1", "gfarga", "b");
                table2.Rows.Add("HHH", "3", "oljoij", "b");
                table2.Rows.Add("bbb", "3", "werewf", "b");
            }
            else
            {
                table2.Rows.Add("あああ", "1", "gerger", "a");
                table2.Rows.Add("いいい", "2", "gfarga", "a");
                table2.Rows.Add("かかか", "1", "oljoij", "a");
                table2.Rows.Add("ききき", "3", "werewf", "a");
                table2.Rows.Add("けけけ", "3", "vn jdnfou", "a");
                table2.Rows.Add("こここ", "4", "ovgjnawoe", "a");
                table2.Rows.Add("くくく", "2", "oiuhjr", "a");
                table2.Rows.Add("ううう", "4", "lmvjrfe", "a");
                table2.Rows.Add("えええ", "2", "tghbdsde", "a");
            }
        }
    }
---------------------------------------------------------------------------

引用返信 編集キー/
■37621 / inTopicNo.5)  Re[4]: DataGridViewComboBoxColumnのデータ
□投稿者/ mori (3回)-(2009/06/26(Fri) 01:25:53)
サンプルありがとうございます。
イメージ的には合っているのですが、データが、
GetData2(true)

table2.Rows.Add("LLL", "5", "gerger", "b");
table2.Rows.Add("FFF", "1", "gfarga", "b");
table2.Rows.Add("HHH", "6", "oljoij", "b");
table2.Rows.Add("bbb", "3", "werewf", "b");
みたいなケースになる場合で、最初に「1〜4」で読み込まれてしまうとComboBoxの選択を変えても上記の「1,3,5,6」に更新されずエラーとなってしまいます。
これを更新させるにはどうすればよいのでしょうか?
引用返信 編集キー/
■37622 / inTopicNo.6)  Re[5]: DataGridViewComboBoxColumnのデータ
□投稿者/ カドルドエグ (91回)-(2009/06/26(Fri) 09:30:01)
No37621 (mori さん) に返信
> table2.Rows.Add("LLL", "5", "gerger", "b");
> table2.Rows.Add("FFF", "1", "gfarga", "b");
> table2.Rows.Add("HHH", "6", "oljoij", "b");
> table2.Rows.Add("bbb", "3", "werewf", "b");
> みたいなケースになる場合で、最初に「1〜4」で読み込まれてしまうとComboBoxの選択を変えても上記の「1,3,5,6」に更新されずエラーとなってしまいます。
> これを更新させるにはどうすればよいのでしょうか?

2つ方法というか思うところが…

(1)単にエラーを握りつぶす
→DataGridViewのDataErrorイベントをハンドルします。
このイベントは「private void dgv_DataError(object sender, DataGridViewDataErrorEventArgs e)」という形で
設定します。
※Visual Studioをご利用ならば、デザイン画面のイベントプロパティ「DataError」欄をダブルクリックすることで
 自動生成されます。
引数:eのCancelプロパティ(Bool型)を設定することでエラーが回避できるようになります。

但し、これはあくまで「エラーから逃げているだけ」です。
このエラーを、DataErrorイベントをハンドルすることで、
とりあえず持ってる値で代用表示して設定を無視している形です。

ご存じとは思いますが、
DataGridViewComboBoxColumn(今回のサンプルでいうcolumn1)は、
DataGridViewのDataSourceに設定されるテーブルとは
別にソースを持っています。

その中で本体側と一致するものがあればその都度表示・値を設定しています。
しかし、DataGridView側だけが持っている値がきてしまうと、column1側は表示/設定のしようがないことで
エラーが発生します。

(2)そもそもDataGridView側だけが持つ値がこないようにする
→(仮に、DataGridViewComboBoxColumnに表示するものを「区分」という表現で表すとして、)
この「区分」を先に登録してもらうという流れにしてしまうなりして
必ずDataGridView本体に登録されている「区分」列に入る値の種類と
DataGridViewComboBoxColumn側で表示される「区分」の種類を一致させるべきでは、
と個人的には思います。

#この辺は仕様の話につっこんじゃうのであまり深くは言えませんが。。。
引用返信 編集キー/
■37763 / inTopicNo.7)  Re[6]: DataGridViewComboBoxColumnのデータ
□投稿者/ mori (4回)-(2009/06/29(Mon) 22:14:32)
返事が遅くなりすいません。
残念ですが、両方とも解決にはなりません。
仕様上、区分の種類を一致させるというのは無理なので。
そもそもこのDataGridViewComboBoxColumnの値が一度設定すると変更できないということであれば
.NETのバグなんでしょうね。
データを格納するコントロールが初期化できないなんて信じられないのですが・・・
何か方法が無いものかもう少し模索してみます。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -