トップ回答者
IDataGridViewEditingControlからDataGridViewTextBoxCellへのデータ渡しについて

質問
-
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が渡っているのでしょうか?
回答
-
編集コントロールからセルへ値が渡される際にはIDataGridViewEditingControl.GetEditingControlFormattedValueメソッドを
利用していると思いました。
(正しくは、セルが値[または表示するモノ]を編集コントロールへ要求する、かな)
このメソッドでは「(セルに表示される)文字列を返却」することも「(セルに設定される)値を返却」することも必要です。
引数contextにDataGridViewDataErrorContexts.Formattingが含まれている(ビットフラグなので)場合は
「セルに表示する」モノを返却する必要がありますし、含まれていない場合は「セルに設定する」値を返却する必要があります。
すべての返信
-
編集コントロールからセルへ値が渡される際にはIDataGridViewEditingControl.GetEditingControlFormattedValueメソッドを
利用していると思いました。
(正しくは、セルが値[または表示するモノ]を編集コントロールへ要求する、かな)
このメソッドでは「(セルに表示される)文字列を返却」することも「(セルに設定される)値を返却」することも必要です。
引数contextにDataGridViewDataErrorContexts.Formattingが含まれている(ビットフラグなので)場合は
「セルに表示する」モノを返却する必要がありますし、含まれていない場合は「セルに設定する」値を返却する必要があります。
-
Ahf 様、ご返答ありがとうございます。
該当部分で、
Code Snippetpublic object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}とやっていたのを、
Code Snippetpublic object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
if ((context & DataGridViewDataErrorContexts.Formatting) != 0)
return EditingControlFormattedValue;
else
return Value;
}と書き改めました。
ステップ実行してみると、たしかにFormattingのピットが立つときと、立たないときがありました。
が、今度は、Valueのみが、渡されてしまいます。
MTextBoxCellのベースクラスがComboBox的なものではなく、DataGirdViewTextBoxCellという「表示=値」という
TextBox的なものだから、うまくいかないのでしょうか?
-
EditingControlFormattedValueプロパティは、この実装です。
なので、GetEditingControlFormattedValueの中でも、Textを返すこのプロパティをそのまま渡していましたが、
念のために、Textに書き改めてみました。残念ながら、 結果は変わりませんでした。
Code Snippetpublic object EditingControlFormattedValue
{
get
{
return Text;
}
set
{
throw new Exception("アイテム名の設定はできません");
}}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
if ((context & DataGridViewDataErrorContexts.Formatting) != 0)
return Text;
else
return Value;
} -
GetFormattedValueメソッドは、知りませんでした。
抽象クラスのDataGridViewCell.GetFormattedValueがあったのですね。
MTextBoxCel.GetFormattedValueは、DataGridViewTextBoxCellから派生しているため、
GetFormattedValueメソッドは、隠蔽されてしまって、存在しませんでした。
これが必要なのですね?
しかし、以下のように実装してみたのですが、まったくDataGridViewから呼んでもらえませんでした。
Code Snippetprotected new virtual Object GetFormattedValue(
Object value,
int rowIndex,
ref DataGridViewCellStyle cellStyle,
TypeConverter valueTypeConverter,
TypeConverter formattedValueTypeConverter,
DataGridViewDataErrorContexts context)
{
return FormattedValue;
}
-
すみません、うっかりvirtualにしていました。
overrideにできたのですが、今度は、エラーが出てしまいました。
System.ArgumentOutOfRangeException はユーザー コードによってハンドルされませんでした。
Message="指定された引数は、有効な値の範囲内にありません。パラメータ名: rowIndex"
Source="System.Windows.Forms"
ParamName="rowIndex"なので、
Code Snippetprotected 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;
}
とやってみましたが、"" だと繰り返されるらしく、今度は、スタックオーバーフローになってしまいます。
-
Ahf様、ありがとうございます!! 解決しました!!
最終的には、以下のようになりました。
Code Snippetprotected 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;
}こんなことは、ここで教えていただかなければ、わかりませんでした。
どこで学べばよいのでしょうか? よい書籍やサイトがあれば教えていただきたいのですが……
-
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
各メソッドをオーバーライドしていくことになります。
-
えムナウ様、お忙しいところ、ご返答感謝いたします。
やはり、MSDNライブラリを隅々までじっくり読んで理解するしかないようですね。
それでも、貴サイトの記事は、学習の大いなる助けで、本当に感謝しています。
DataGridView(に限らずですが……)は、結構奥深く、それぞれのメソッドやプロパティが内部で関係しており、
MSDNにおける「個々のメンバの解説ページだけではわからない」というのが正直な感想です。ですから、
DataGridViewに関するページを一通り隅々まで読んで理解する必要があるのだと感じました。
ただ、えムナウ様のご返答からするに、参考ソースは「MSDNライブラリ」ということになります。Ahf様にしても、皆様は、
少なくとも、DataGridViewのカスタマイズについては、MSDNから学ばれているということなのですから、
これは、MSDNから学ぶ私の姿勢が甘いということだと思います。
ですから、MSDNからの学習をより深めていきたいと思います。今は、無力で誰の助けにもなりえませんが、
誰かの一助となれる日を目指して……