DOBON.NET DOBON.NETプログラミング掲示板過去ログ

C#のdatagridにcombobox

  • 題名: C#のdatagridにcombobox
  • 著者: グリグリ
  • 日時: 2005/12/01 20:04:10
  • ID: 14011
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[C#]
分類:[.NET]

2005/12/02(Fri) 11:59:38 編集(投稿者)

こんにちわ。
どなたか教えてください。

ここのサイトに載っているdatagridにcomboboxを表示させるようにしています。
表示されている値はとってこれるのですが、comboboxが持っている値をとってくることが出来ません。どのようにしたら値を取得できるでしょうか。
よろしくお願いします。
お世話になります。

こちらですか?
http://dobon.net/vb/dotnet/datagrid/datagridcombobox.html

DataGridComboBoxColumn にアクセサを作ってやればよさそうな感じがしますが、
ちょっとおかしくないですか?

もしnew する時以降で、再度必要になるんだったら、
new した時に使った DataTable 等を、メンバ変数などで保持しておけば
いいんじゃないでしょうか?

■No14011に返信(初心者さんの記事)
> こんにちわ。
> どなたか教えてください。
>
> ここのサイトに載っているdatagridにcomboboxを表示させるようにしています。
> 表示されている値はとってこれるのですが、comboboxが持っている値をとってくることが出来ません。どのようにしたら値を取得できるでしょうか。
> よろしくお願いします。
>
回答、ありがとうございます。

先ほど指定したサイトはこちらでした。
http://codezine.jp/a/article.aspx?aid=3

> DataGridComboBoxColumn にアクセサを作ってやればよさそうな感じがしますが、
> ちょっとおかしくないですか?
>
> もしnew する時以降で、再度必要になるんだったら、
> new した時に使った DataTable 等を、メンバ変数などで保持しておけば
> いいんじゃないでしょうか?
すみません。知識不足でよく理解できません。
もう少し詳しく教えていただけないでしょうか?
お世話になります。

■No14013に返信(初心者さんの記事)
> 回答、ありがとうございます。
>
> 先ほど指定したサイトはこちらでした。
> http://codezine.jp/a/article.aspx?aid=3
>
>>DataGridComboBoxColumn にアクセサを作ってやればよさそうな感じがしますが、
>>ちょっとおかしくないですか?
DataGridComboBoxColumn に以下のコードを追加。
private object m_datasource;

public object DataSource
{
  get
  {
    return this.m_datasource;
  }
}
で、コンストラクタの中で以下のコードを追加。
this.m_datasource = dataSource;

でも、dataSource にセットする値をを作っているのは誰でしょう。
作った人が持っておけば済むのでは?
という事で...

>>もしnew する時以降で、再度必要になるんだったら、
>>new した時に使った DataTable 等を、メンバ変数などで保持しておけば
>>いいんじゃないでしょうか?
DataTable comboSorce = new DataTable("ComboBox");
としてあるところを
メソッドの外で
private DataTable comboSorce;
と宣言し、
this.comboSorce = new DataTable("ComboBox");
返信遅くなりました。
回答ありがとうございます。
上記述を試してみます。
#「初心者」というお名前は、この掲示板ではマナー違反となります。詳しくは、「書き込みのマナーについて」をご覧ください。

http://dobon.net/vb/bbs/index.html

DataGridで使用しているComboBoxはパブリックプロパティで公開していたと思いましたが...。
お世話になります。


■No14018に返信(管理人さんの記事)
> #「初心者」というお名前は、この掲示板ではマナー違反となります。詳しくは、「書き込みのマナーについて」をご覧ください。
>
> http://dobon.net/vb/bbs/index.html
名前のつけかたについて了解しました。
初心者→グリグリに変更しました。


> DataGridで使用しているComboBoxはパブリックプロパティで公開していたと思いましたが...。
申し訳ありません。いろいろ試してみたのですが、よくわかりません。
実際に値のとり方についての書き方を教えていただけないでしょうか?
>>DataGridで使用しているComboBoxはパブリックプロパティで公開していたと思いましたが...。
> 申し訳ありません。いろいろ試してみたのですが、よくわかりません。
> 実際に値のとり方についての書き方を教えていただけないでしょうか?

グリグリさんのおっしゃる「値」というものは、ComboBoxのSelectedValueで取得できる値とは違うのでしょうか?もしそうであれば、グリグリさんのおっしゃる「値」とは何ですか?
お世話になります。

> グリグリさんのおっしゃる「値」というものは、ComboBoxのSelectedValueで取得できる値とは違うのでしょうか?もしそうであれば、グリグリさんのおっしゃる「値」とは何ですか?
SelectedValueの値です。この記述をみていくつか試してみたのですがexceptionが発生してしまいました。
お世話になります。

■No14055に返信(グリグリさんの記事)
>>グリグリさんのおっしゃる「値」というものは、ComboBoxのSelectedValueで取得できる値とは違うのでしょうか?もしそうであれば、グリグリさんのおっしゃる「値」とは何ですか?
> SelectedValueの値です。この記述をみていくつか試してみたのですがexceptionが発生してしまいました。

そうでしたか、Selected Value の方でしたか。
私はてっきり、DataSource のことだと思ってました。すみません。
↓の一番下にあるコード例を基に
http://dobon.net/vb/dotnet/datagrid/datagridcombobox.html
いじってみました。
Console.WriteLine で出力している値の上の方でしょうか。
# どぼん!さん、使い方を間違ってたらご指摘下さい。

private DataTable m_dt;
private DataTable m_comboSorce;

private void button1_Click(object sender, System.EventArgs e)
{
  //DataGridに表示するDataTableの作成
  this.m_dt = new DataTable("DataTable1");
  this.m_dt.Columns.Add("Column1", typeof(int));
  this.m_dt.Rows.Add(new object[] {5});
  this.m_dt.Rows.Add(new object[] {9});
  this.m_dt.Rows.Add(new object[] {3});

  //DataGridで表示するデータソースに設定
  dataGrid1.DataSource = this.m_dt;

  //DataGridTableStyleの作成
  DataGridTableStyle ts = new DataGridTableStyle();
  ts.MappingName = "DataTable1";

  //DataGridComboBoxColumnで使用するDataTableの作成
  //"DisplayMember"列はComboBoxに表示される値
  //"ValueMember"列は実際の値
  this.m_comboSorce = new DataTable("ComboBox");
  this.m_comboSorce.Columns.Add("DisplayMember", typeof(string));
  this.m_comboSorce.Columns.Add("ValueMember", typeof(int));
  this.m_comboSorce.Rows.Add(new object[] {"一", 1});
  this.m_comboSorce.Rows.Add(new object[] {"二", 2});
  this.m_comboSorce.Rows.Add(new object[] {"三", 3});
  this.m_comboSorce.Rows.Add(new object[] {"四", 4});
  this.m_comboSorce.Rows.Add(new object[] {"五", 5});
  this.m_comboSorce.Rows.Add(new object[] {"六", 6});
  this.m_comboSorce.Rows.Add(new object[] {"七", 7});
  this.m_comboSorce.Rows.Add(new object[] {"八", 8});
  this.m_comboSorce.Rows.Add(new object[] {"九", 9});
  this.m_comboSorce.Rows.Add(new object[] {"十", 10});

  //DataGridComboBoxColumnの作成
  Dobon.Samples.Forms.DataGridComboBoxColumn cbc =
    new Dobon.Samples.Forms.DataGridComboBoxColumn(
    this.m_comboSorce.DefaultView, "DisplayMember", "ValueMember");
  //表示される値と実際の値が同じでよければ、次のようにもできる
  //Dobon.Samples.Forms.DataGridComboBoxColumn cbc =
  // new Dobon.Samples.Forms.DataGridComboBoxColumn(
  // comboSorce.DefaultView, "ValueMember", "ValueMember");
  cbc.MappingName = "Column1";
  cbc.HeaderText = "数字";

  //列スタイルの追加
  ts.GridColumnStyles.Add(cbc);

  //テーブルスタイルの追加
  dataGrid1.TableStyles.Add(ts);

}

private void button2_Click(object sender, System.EventArgs e)
{
  int ValueMemberValue = -1;
  string DisplayMemberValue = null;
  
  DataRow row = this.m_dt.Rows[this.dataGrid1.CurrentRowIndex];
  ValueMemberValue = (int)row[0];

  DataRow[] rows = this.m_comboSorce.Select("ValueMember=" + ValueMemberValue.ToString());
  if (rows.Length > 0) {
    DisplayMemberValue = (string)rows[0]["DisplayMember"];
  }
  Console.WriteLine("選択されている行の先頭列で、選択されている値(表示):" + DisplayMemberValue);
  Console.WriteLine("選択されている行の先頭列で、選択されている値(中で持ってる値):" + ValueMemberValue.ToString());
}
なおこさん、管理人さんありがとうございます。
なおこさんの記述で値を取ることが出来ました。
もし、他の記述方法などあれば、また教えてください。
#いまさら蛇足になってしまいそうですが...。

DataGridTextBoxColumnではComboBoxプロパティを公開していますので、現在選択されている項目の値であれば、そのままSelectedValueで取れます。また、このComboBoxにはFindValueMemberメソッドがあり、これによりDisplayMemberからValueMemberの値を探すことができます(詳しくは、ソースコードをご覧ください)。
>> 管理人様
お世話になります。

■No14066に返信(管理人さんの記事)
> DataGridTextBoxColumnではComboBoxプロパティを公開していますので、現在選択されている項目の値であれば、そのままSelectedValueで取れます。また、このComboBoxにはFindValueMemberメソッドがあり、これによりDisplayMemberからValueMemberの値を探すことができます(詳しくは、ソースコードをご覧ください)。

ご指摘、ありがとうございます。
管理人様のご指摘に基づきまして修正してみたのですが、
あってますでしょうか...。

private void button1_Click(object sender, System.EventArgs e)
{
  //DataGridに表示するDataTableの作成
  DataTable dt = new DataTable("DataTable1");
  dt.Columns.Add("Column1", typeof(int));
  dt.Rows.Add(new object[] {5});
  dt.Rows.Add(new object[] {9});
  dt.Rows.Add(new object[] {3});

  //DataGridで表示するデータソースに設定
  dataGrid1.DataSource = dt;

  //DataGridTableStyleの作成
  DataGridTableStyle ts = new DataGridTableStyle();
  ts.MappingName = "DataTable1";

  //DataGridComboBoxColumnで使用するDataTableの作成
  //"DisplayMember"列はComboBoxに表示される値
  //"ValueMember"列は実際の値
  DataTable comboSorce = new DataTable("ComboBox");
  comboSorce.Columns.Add("DisplayMember", typeof(string));
  comboSorce.Columns.Add("ValueMember", typeof(int));
  comboSorce.Rows.Add(new object[] {"一", 1});
  comboSorce.Rows.Add(new object[] {"二", 2});
  comboSorce.Rows.Add(new object[] {"三", 3});
  comboSorce.Rows.Add(new object[] {"四", 4});
  comboSorce.Rows.Add(new object[] {"五", 5});
  comboSorce.Rows.Add(new object[] {"六", 6});
  comboSorce.Rows.Add(new object[] {"七", 7});
  comboSorce.Rows.Add(new object[] {"八", 8});
  comboSorce.Rows.Add(new object[] {"九", 9});
  comboSorce.Rows.Add(new object[] {"十", 10});

  //DataGridComboBoxColumnの作成
  Dobon.Samples.Forms.DataGridComboBoxColumn cbc =
    new Dobon.Samples.Forms.DataGridComboBoxColumn(
    comboSorce.DefaultView, "DisplayMember", "ValueMember");
  //表示される値と実際の値が同じでよければ、次のようにもできる
  //Dobon.Samples.Forms.DataGridComboBoxColumn cbc =
  // new Dobon.Samples.Forms.DataGridComboBoxColumn(
  // comboSorce.DefaultView, "ValueMember", "ValueMember");
  cbc.MappingName = "Column1";
  cbc.HeaderText = "数字";

  //列スタイルの追加
  ts.GridColumnStyles.Add(cbc);

  //テーブルスタイルの追加
  dataGrid1.TableStyles.Add(ts);
}

private void button2_Click(object sender, System.EventArgs e)
{
  int ValueMemberValue = -1;
  string DisplayMemberValue = null;
  Dobon.Samples.Forms.DataGridComboBoxColumn cbc;
  cbc = (Dobon.Samples.Forms.DataGridComboBoxColumn)this.dataGrid1.TableStyles[0].GridColumnStyles[0];
  ValueMemberValue = (int)cbc.ComboBox.SelectedValue;
  DisplayMemberValue = cbc.ComboBox.FindDisplayMember(ValueMemberValue).ToString();
  Console.WriteLine("選択されている値(表示):" + DisplayMemberValue);
  Console.WriteLine("選択されている値(中で持ってる値):" + ValueMemberValue.ToString());
}
2005/12/05(Mon) 14:19:34 編集(投稿者)

こんにちわ。

追加記述ありがとうございます。

> private void button2_Click(object sender, System.EventArgs e)
> {
>   int ValueMemberValue = -1;
>   string DisplayMemberValue = null;
>   Dobon.Samples.Forms.DataGridComboBoxColumn cbc;
>   cbc = (Dobon.Samples.Forms.DataGridComboBoxColumn)this.dataGrid1.TableStyles[0].GridColumnStyles[0];
>   ValueMemberValue = (int)cbc.ComboBox.SelectedValue;
>   DisplayMemberValue = cbc.ComboBox.FindDisplayMember(ValueMemberValue).ToString();
>   Console.WriteLine("選択されている値(表示):" + DisplayMemberValue);
>   Console.WriteLine("選択されている値(中で持ってる値):" + ValueMemberValue.ToString());
> }

上記、
cbc = (Dobon.Samples.Forms.DataGridComboBoxColumn)this.dataGrid1.TableStyles[0].GridColumnStyles[0];
ValueMemberValue = (int)cbc.ComboBox.SelectedValue;
のあたりで「オブジェクト参照がオブジェクト インスタンスに設定されていません。」というエラーが出てしまいますが、自分だけでしょうか?また各行の値をループさせて取りたい場合、なおこさんが記述している2種類のソースの内、どちらを使うのが妥当でしょうか?
> なおこ(・∀・)様へ

わざわざコードを書いていただき、ありがとうございました。

> cbc = (Dobon.Samples.Forms.DataGridComboBoxColumn)this.dataGrid1.TableStyles[0].GridColumnStyles[0];
> ValueMemberValue = (int)cbc.ComboBox.SelectedValue;
> のあたりで「オブジェクト参照がオブジェクト インスタンスに設定されていません。」というエラーが出てしまいますが、自分だけでしょうか?

「あたり」ではなく、どこなのか明記してください。簡単に分かるはずで、なぜあいまいにするのか、理解できません。

仮に後者の行だとすると、ボタンをクリックしたためにComboBoxが非表示になり、
SelectedValueが空になった可能性があります。

「表示されている値はとってこれる」ということなので、FindValueMemberメソッドでご希望の値が取れるでしょう。
  • 題名: Re[15]: C#のdatagridにcombobox
  • 著者: グリグリ
  • 日時: 2005/12/06 10:41:55
  • ID: 14088
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
あいまいな記述、すみませんでした。
問題は一応、解決致しました。
ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板