- PR -

object型のプロパティを持つコントロール

1
投稿者投稿内容
Furi2
ベテラン
会議室デビュー日: 2004/10/28
投稿数: 74
お住まい・勤務地: N.Hollywood/Agoura Hills
投稿日時: 2006-08-29 18:47
こんにちは、いつもお世話になっています。

TextBoxから継承させて、カスタムTextBoxコントロールの使用に挑戦しているのですが、プロパティーを加えて、

public object TestProperty
{
get { return ViewState["TestProperty"]; }
set { ViewState["TestProperty"] = value; }
}

というように、このコントロールにいかなるオブジェクトも関連付けて保持できるようにしたい、と思いました(例えばSqlParameter.Valueのように、何でもOKなプロパティーを加えたかった)。

すると、プロパティ・ウィンドからこのプロパティーに値を与えようと思っても、編集不可にされてしまっています。タグに直接書き込んで、例えば

<uc:CustomTextBox ID="txt" runat="server" TestProperty="Hello"></uc:CustomTextBox>

などとすると、デザインモードのページでは、

Cannot create an object of type 'System.Object' from its string representation 'Hello' for the 'TestProperty' property.

とグレーのボックスにエラー表示されてしまい、コンパイルすらできません。

デザイン時にこのプロパティーの設定をしないでおくと、通常のTextBoxのごとく表示され、コンパイルもされ、問題なく実行もでき、コードから実際このプロパティーを有用に使うことができます。

しかし例えデザイン時にこのプロパティーを設定しなくても、例えばこのカスタムTextBoxがWizardコントロールの中にあったりすると、やはり上記のエラーメッセージがグレーのボックスに表示されてしまいます。ただこの場合、なぜかコンパイルはされ、実行も問題はないので、エラー表示だらけの醜いデザインモード画面を無視すれば、何とか使えるのですが、どうも気分がよくありません。。

これは結局、コントロールのプロパティにはobject型(System.Object型)を使うな、ということなんでしょうか??それとも他に迂回方法があるのでしょうか??

書き遅れましたが、ASP2.0, VS2005 Proを使用しています。

[ メッセージ編集済み 編集者: Furi2 編集日時 2006-08-29 18:53 ]
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-08-29 19:01
コントロール?
だったらTagプロパティが参考になる。
Furi2
ベテラン
会議室デビュー日: 2004/10/28
投稿数: 74
お住まい・勤務地: N.Hollywood/Agoura Hills
投稿日時: 2006-08-29 19:12
そうなんです、目指すところはまさに、WindowsコントロールのTagプロパティをWebコントロールで!とトライしていたのですが、その結果が上記の通りです。。

もしよろしければ、どんな風にTagプロパティをWebコントロールに実装するのか、もう一歩だけ踏み込んで教えていただけると、大変うれしいです。
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2006-08-29 19:35
デザイナでエラーが発生するのは、そのまま書いてあると思うが、たぶんSytem.Objectに対応する規定の TypeConverter が見つからないから。
デザイン(タグの属性)から指定する型がSystem.String固定なら固定的なTypeConverter作って指定してやればOKなはず。
色々いじりたいんなら、Editorをカスタマイズする必要もあるかもしれない。

この辺の基本は「デザイン時サポート」あたりの言葉でMSDNあさると見つかると思う。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-08-29 23:06
引用:

タグに直接書き込んで、例えば

<uc:CustomTextBox ID="txt" runat="server" TestProperty="Hello"></uc:CustomTextBox>

などとすると、デザインモードのページでは、

Cannot create an object of type 'System.Object' from its string representation 'Hello' for the 'TestProperty' property.
「TestProperty」プロパティのためにその文字列表記「Hello」からタイプ「System.Object」のオブジェクトを作成することができません。

とグレーのボックスにエラー表示されてしまい、コンパイルすらできません。


 ご自分で "Hello" と書かれているように、HTML に表現できなければ、設定できないのです。Object 型であれば、表現できるのかどうかわかりません。このため、設定できないのです。

 ここで、"Hello" というのが文字列であることは、人間には想像できるでしょう。しかし、機械にはわからなかったようです。
 では、「TestProperty="1"」だったら、この "1" は、文字列ですか?文字ですか?整数値ですか?あるいは Single かもしれないし、そんなこと言いだしたら Double の可能性もある。TimeSpan かもしれない。

 どんな型であろうと、HTML ページ上に書かれる以上、文字列に出来なければならないし、文字列から生成できなければならない。この点で、Object は「何でもあり」である故に、無理でしょう。
Furi2
ベテラン
会議室デビュー日: 2004/10/28
投稿数: 74
お住まい・勤務地: N.Hollywood/Agoura Hills
投稿日時: 2006-08-30 06:48
yaさん、Jittaさん、ご返信どうもありがとうございます。

すみません、正直皆さんのアドバイスが飲み込めていません。。原則としてJittaさんのおっしゃるように無理だけれど、yaさんの方法をとれば実装可、ということと考えてよいのでしょうか??

とするとまた色々疑問がでてきてしまいました。

エラーメッセージは、Jittaさんのおっしゃるとおり、○型から○型へ変換できません、というよりは、"Hello"という値の型が全くわかりません、と言っているように思いました。System.Objectとしてさえも扱ってもらえていないように見えます。

引用:

デザイナでエラーが発生するのは、そのまま書いてあると思うが、たぶんSytem.Objectに対応する規定の TypeConverter が見つからないから。
デザイン(タグの属性)から指定する型がSystem.String固定なら固定的なTypeConverter作って指定してやればOKなはず。



ということは、TypeConverterを何かしらの形で使って、「実際のプロパティの値としてはObject型であるけれど、デザイン時に指定された値は、常にSystem.Stringとして扱ってください」と、エディタ/デザイナに指示すればOK、ということですよね。。??
自分なりにドキュメントを読んだのですが、その方法がわかりませんでした。

TypeConverterは、特定の型を特定の型への変換定義の為のものだと理解したのですが、その元々の型を「特定」出来ない場合(Objectですらない場合)、一体どのように定義をしたらよいのでしょうか?


ちなみにこのプロパティはコード側からしか使わない、としてしまうこともできるので、 [Browsable(false)]と指定して、デザイン時の編集不可にしました。しかしやはりデザイン・ビューではグレーのボックスに同じエラーメッセージを表示されてしまいます。(もちろん今回は'Hello'の代わりに''と表示される。)
実行時にはなんの問題ないのですが、、ただデザイン・ビューのエラー表示が気になるのみです。
最悪、SetValue(), GetValue() で行こうかな、とも考えています。


自分でも問題が100%理解できていないので、訳のわからないことを質問していたら申し訳ありません。。

[ メッセージ編集済み 編集者: Furi2 編集日時 2006-08-30 06:56 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-08-30 21:06
 指摘するのを忘れていました。
引用:

public object TestProperty
{
get { return ViewState["TestProperty"]; }
set { ViewState["TestProperty"] = value; }
}

というように、このコントロールにいかなるオブジェクトも関連付けて保持できるようにしたい、と思いました(例えばSqlParameter.Valueのように、何でもOKなプロパティーを加えたかった)。


 残念ながら、このコードでは、TestProperty に“何でも”しまうことは出来ません。ViewState にしまうことが出来るのは、“シリアライズ可能なオブジェクト”(または、文字列からパースできるオブジェクト)だけだからです。
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2006-08-31 07:14
そんなに数日で理解できるような内容でもないというか、System.ComponentModelのある程度の仕組みと知識、ASPについての知識が必要だから(「デザイン時サポート」でぐぐれば一番初めに来るし目ぐらいは通したよね?)。あと手探り調査。

まぁそれはいいとして、System.String固定でいいなら、TypeConverterのConvertFromにSystem.Stringからの変換を定義するだけでいけるんじゃないかな(無保証。ASPのパーサー、デザイナの動作を精査したことなんてないし…いやあったかもしれないけど忘れた)。

自由な型にしたいなら、「発想を逆転させるのよ」で、「型が特定できない」なら「特定できるような情報をSystem.Stringにもたせればいい」だけ。

以下は何も考えてない例だけど、それこそ、

コード:

<my:Sample id="sample" runat="server" Property="[System.Int32]32" />



とでもすればいい。この場合、TypeConverterはこの文字列を解釈するように実装ね。

※パーサ、デザイナがSystem.StringとしてTag Attibuteを解釈して渡してきて、それをもとにデザイナシリアライゼーションやらを構築していくと仮定しています(なんか記憶ではパーサーの解釈においてもカスタマイズできた気がするから間違っているかもしれない)。

ASP的な問題点も多い。Serializationについてまったく考慮していないし、保存、読み込むタイミングも変だし、IDについての考慮もなしと(それと、対応をはずすならBrowsable(false) だけじゃなくて DesignerSerializationVisibility はいらないんだっけ?)。

# カスタムコンポーネントは一回まとめてみたいとか思ってんだけど、
# そのままだなぁ
1

スキルアップ/キャリアアップ(JOB@IT)