none
IDataGridViewEditingControlからDataGridViewTextBoxCellへのデータ渡しについて RRS feed

  • 質問

  • DataGridViewにカスタマイズした列とセルを作っています。

    http://msdn2.microsoft.com/ja-jp/library/7tas5c80.aspx

    http://mnow.wankuma.com/cs2005_datagridview_control5.html

    http://dobon.net/vb/dotnet/datagridview/progressbar.html

    上記のページを参考にして(えムナウ様、どぼん!様<順不同>に感謝)、作ってみたのですが、

    DataGridViewTextBoxCell継承クラスに値がわたる時点で、FormattedValueはうまく渡せているのに、

    ValueがFormattedValueと同じ値になり、困っています。

     

    IDataGridViewEditingControlを実装したクラスは、以下MEditingControlと呼びます。そして、このクラスは、

    MTextBoxという複合コントロールクラスを継承しています。名前にTextBoxが付きますが、TextBoxの派生クラスではなく、

    複合コントロールです。MTextBoxは、必要な値を、Value(実際の値)とText(表示用)とに格納しています。

     

    MEditingGontrolのEditingControlFormattedValueプロパティには、base.Textを返すようにしていますので、

    値の譲渡先であるDataGridViewTextBoxCell継承クラス(以下MTextBoxCellクラスと呼びます)にTextの値は

    ちゃんと渡るのですが、Valueの値が渡されないのです。MEditingGontrol.Valueには、ちゃんとした値が

    入っていることは、確認しています。

    MEditingGontrolでは、

    .FormattedValue="あいうえお"      .Value="12345"

    であるのに、

    MTextBoxCellにデータが渡ってから調べると、

    .FormattedValue="あいうえお"      .Value="あいうえお"

    となってしまうのです。

    MEditingGontrolからMTextBoxCellクラスに、データがわたる時に、うまくいっていないのだろうと思います。

     

    IDataGridViewEditingControlを実装したクラスから、

    どのタイミングで、どのようにしてDataGridViewTextBoxCell継承クラスにValueが渡っているのでしょうか?

     

     

     

    2007年8月24日 2:48

回答

  • 編集コントロールからセルへ値が渡される際にはIDataGridViewEditingControl.GetEditingControlFormattedValueメソッドを

    利用していると思いました。

    (正しくは、セルが値[または表示するモノ]を編集コントロールへ要求する、かな)

     

    このメソッドでは「(セルに表示される)文字列を返却」することも「(セルに設定される)値を返却」することも必要です。

    引数contextにDataGridViewDataErrorContexts.Formattingが含まれている(ビットフラグなので)場合は

    「セルに表示する」モノを返却する必要がありますし、含まれていない場合は「セルに設定する」値を返却する必要があります。

     

    2007年8月24日 3:54
  • GetFormattedValueメソッドの中ですので、FormattedValueプロパティを利用しないで、

    value引数にわたってきたセルの値を、表示するものに変換してあげればいいかと思います。

     

    本当は引数としてわたってくる二つのTypeConverterを利用するのがいいんでしょうけど、

    nullがわたってくることもあるみたいですし。

     

    2007年8月24日 14:03

すべての返信

  • 編集コントロールからセルへ値が渡される際にはIDataGridViewEditingControl.GetEditingControlFormattedValueメソッドを

    利用していると思いました。

    (正しくは、セルが値[または表示するモノ]を編集コントロールへ要求する、かな)

     

    このメソッドでは「(セルに表示される)文字列を返却」することも「(セルに設定される)値を返却」することも必要です。

    引数contextにDataGridViewDataErrorContexts.Formattingが含まれている(ビットフラグなので)場合は

    「セルに表示する」モノを返却する必要がありますし、含まれていない場合は「セルに設定する」値を返却する必要があります。

     

    2007年8月24日 3:54
  • Ahf 様、ご返答ありがとうございます。

    該当部分で、

    Code Snippet

            public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
            {
                    return EditingControlFormattedValue;
            }

    とやっていたのを、

    Code Snippet

            public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
            {
                if ((context & DataGridViewDataErrorContexts.Formatting) != 0)
                    return EditingControlFormattedValue;
                else
                    return Value;
            }

    と書き改めました。

    ステップ実行してみると、たしかにFormattingのピットが立つときと、立たないときがありました。

    が、今度は、Valueのみが、渡されてしまいます。

     

    MTextBoxCellのベースクラスがComboBox的なものではなく、DataGirdViewTextBoxCellという「表示=値」という

    TextBox的なものだから、うまくいかないのでしょうか?

    2007年8月24日 5:23
  • IDataGridViewEditingControl.EditingControlFormattedValueプロパティで値(Value)を返却しています?

     

    ロジックを見るとプロパティの値をそのまま返却している様子ですので。

    ここをセルに表示するものを返却するようにしてみてはどうでしょう。

     

    EditingControlFormattedValueプロパティは表示用のものを返却する、でいいのですが、

    GetEditingControlFormattedValueメソッドはそれだけではない、というところです。

    2007年8月24日 9:11
  • EditingControlFormattedValueプロパティは、この実装です。

    なので、GetEditingControlFormattedValueの中でも、Textを返すこのプロパティをそのまま渡していましたが、

    念のために、Textに書き改めてみました。残念ながら、 結果は変わりませんでした。

    Code Snippet

            public object EditingControlFormattedValue
            {
                get
                {
                    return Text;
                }
                set
                {
                    throw new Exception("アイテム名の設定はできません");
                }

            }

            

     

            public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
            {
                if ((context & DataGridViewDataErrorContexts.Formatting) != 0)
                    return Text;
                else
                    return Value;
            }

     

     

    2007年8月24日 10:19
  • となると、MTextBoxCell.GetFormattedValueではどのような実装をされてるのでしょうか?

     

    このメソッドが呼ばれた際に引数valueにセルの値が入ってきていれば、そこまでの制御は大丈夫だと思います。

    ここでセルに表示するものを返却するようになっていればOKそうなんですが・・・。

    2007年8月24日 11:00
  • GetFormattedValueメソッドは、知りませんでした。

    抽象クラスのDataGridViewCell.GetFormattedValueがあったのですね。

     

    MTextBoxCel.GetFormattedValueは、DataGridViewTextBoxCellから派生しているため、

    GetFormattedValueメソッドは、隠蔽されてしまって、存在しませんでした。

    これが必要なのですね? 

    しかし、以下のように実装してみたのですが、まったくDataGridViewから呼んでもらえませんでした。

    Code Snippet
            protected new virtual Object GetFormattedValue(
                Object value,
                int rowIndex,
                ref DataGridViewCellStyle cellStyle,
                TypeConverter valueTypeConverter,
                TypeConverter formattedValueTypeConverter,
                DataGridViewDataErrorContexts context)
            {
                return FormattedValue;
            }

     

     

     

    2007年8月24日 11:55
  • あれ?DataGridViewTextBoxCell.GetFormattedValueメソッドってOverridesできませんでした?

     

    こちらでもDataGridViewTextBoxCellから派生させたセルクラスを作成したものがありますけど、

    Overridesできました。

    2007年8月24日 12:06
  • すみません、うっかりvirtualにしていました。

    overrideにできたのですが、今度は、エラーが出てしまいました。

     

    System.ArgumentOutOfRangeException はユーザー コードによってハンドルされませんでした。
      Message="指定された引数は、有効な値の範囲内にありません。パラメータ名: rowIndex"
      Source="System.Windows.Forms"
      ParamName="rowIndex"

     

    なので、

    Code Snippet
            protected override Object GetFormattedValue(
                Object value,
                int rowIndex,
                ref DataGridViewCellStyle cellStyle,
                TypeConverter valueTypeConverter,
                TypeConverter formattedValueTypeConverter,
                DataGridViewDataErrorContexts context)
            {
                if (this.RowIndex == -1) return "";
                    return FormattedValue as string;
            }

     

     

    とやってみましたが、"" だと繰り返されるらしく、今度は、スタックオーバーフローになってしまいます。

     

    2007年8月24日 13:07
  • GetFormattedValueメソッドの中ですので、FormattedValueプロパティを利用しないで、

    value引数にわたってきたセルの値を、表示するものに変換してあげればいいかと思います。

     

    本当は引数としてわたってくる二つのTypeConverterを利用するのがいいんでしょうけど、

    nullがわたってくることもあるみたいですし。

     

    2007年8月24日 14:03
  • Ahf様、ありがとうございます!! 解決しました!!

     

    最終的には、以下のようになりました。

    Code Snippet

            protected override Object GetFormattedValue(
                Object value,
                int rowIndex,
                ref DataGridViewCellStyle cellStyle,
                TypeConverter valueTypeConverter,
                TypeConverter formattedValueTypeConverter,
                DataGridViewDataErrorContexts context)
            {
                if (this.RowIndex == -1) return "";
                DataGridViewMasterTextBoxColumn col = this.OwningColumn as DataGridViewMasterTextBoxColumn;
                if (col != null && value!=null)
                {
                    return ValueからTextへの変換処理(value);
                }
                    return value;
            }

     

     

    こんなことは、ここで教えていただかなければ、わかりませんでした。

    どこで学べばよいのでしょうか? よい書籍やサイトがあれば教えていただきたいのですが……

    2007年8月25日 2:02
  • TechEd期間ということもあって書き込みできずに申し訳なかったです。

    本件は解決したようでよかったです。

     

    とりあえず公式のページはここになります。

    http://msdn2.microsoft.com/ja-jp/library/e0ywh3cz(VS.80).aspx

     

    DataGridView コントロールのカスタマイズはこの下です。

    http://msdn2.microsoft.com/ja-jp/library/ms171618(VS.80).aspx

     

    このページを基礎として

    IDataGridViewEditingControl インターフェイス、DataGridViewCell、DataGridViewColumn

     各メソッドをオーバーライドしていくことになります。

     

    2007年8月25日 5:14
  • えムナウ様、お忙しいところ、ご返答感謝いたします。

    やはり、MSDNライブラリを隅々までじっくり読んで理解するしかないようですね。

    それでも、貴サイトの記事は、学習の大いなる助けで、本当に感謝しています。

     

    DataGridView(に限らずですが……)は、結構奥深く、それぞれのメソッドやプロパティが内部で関係しており、

    MSDNにおける「個々のメンバの解説ページだけではわからない」というのが正直な感想です。ですから、

    DataGridViewに関するページを一通り隅々まで読んで理解する必要があるのだと感じました。

     

    ただ、えムナウ様のご返答からするに、参考ソースは「MSDNライブラリ」ということになります。Ahf様にしても、皆様は、

    少なくとも、DataGridViewのカスタマイズについては、MSDNから学ばれているということなのですから、

    これは、MSDNから学ぶ私の姿勢が甘いということだと思います。

    ですから、MSDNからの学習をより深めていきたいと思います。今は、無力で誰の助けにもなりえませんが、

    誰かの一助となれる日を目指して……

    2007年8月25日 17:41