- PR -

[VB2005] DefaultValue に定数以外を使用したい

投稿者投稿内容
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-11-08 03:13
引用:

こばさんさんの書き込み (2007-11-07 20:24) より:
 標準の TextBox から継承した UserTextBox コントロールにおいて、BackColor の既定値を My.MySettings.Default.〜 に定義した色(IDEからはアプリケーションの設定で行え、.config ファイルに内容が書かれる)にする、というのは不可能なんでしょうか?



IDEから自動で.configに書いたりするのはすごくいやですが。

引用:

 My.MySettings.Default.TextBoxBackColor に相当する色をプログラム内に定数で書くことには抵抗あります。
 System.ComponentModel.DefaultValue 〜 を書かないと、案の定コントロールを張った先で Me.UserTextBox.BackColor = 〜 とコードが出来てしまいます。

 貼った先で BackColor を My.MySettings.Default.TextBoxBackColor に Binding すれば結果的に所望の動作はするのですが、何となく美しくありません。

 何か良い手はないでしょうか。



えーと、たぶん、コントロールのライブラリを作ってるんですよね?
それで、コントロールを貼り付けたとき、
そのコントロールのプロパティの規定値とか初期値の振舞いを
自分で何とかしたいのですよね?

でしたら、たぶん、良い手があります。

これはデザイナのカスタマイズの問題で、
その辺を調べればいろいろ資料が見つかると思います。
たぶん、DefaultValueではなく、
ShouldSerializeXXXとResetXXXを使うといいかなと。
こんな感じで。

コード:

Private _backcolor As Color = Color.Empty
Public Property BackColor() As Color
Get
If _backcolor = Color.Empty Then
Return My.MySettings.Default.TextBoxBackColor
End If
Return _backcolor
End Get
Set(ByVal value As Color)
_backcolor = value
End Set
End Property

Protected Function ShouldSerializeBackColor() As Boolean
Return _backcolor = Color.Empty
End Function

Protected Sub ResetBackColor()
_backcolor = Color.Empty
End Sub



これでやりたいことができるのではないかと。

動作は未確認です。
OverrideとかShadowsとかは適当に入れてください。
My.MySettings.Default.TextBoxBackColorが
無い時の処理とかもいれないといけません。

適当なコントロールを作って貼り付けて見れば分かるのですが、
軽く説明しときます。

最初_backcolorはColor.Emptyです。

_backcolor=Color.Emptyの場合、
BackColorプロパティはMy.MySettings.Default.TextBoxBackColorを返すので、
My.MySettings.Default.TextBoxBackColorに規定値を設定しておけば
これを背景色として使ってくれます。

IDEのデザイナのプロパティウィンドウからBackColorプロパティを変えると、
その色が_backcolorに設定されるので、
以降はその色を背景色として使ってくれるようになります。

My.MySettings.Default.TextBoxBackColorを使いたい時は、
プロパティウィンドウの背景のプロパティの項を右クリックして
リセットすれば、_backcolor=Color.Emptyになるので、
My.MySettings.Default.TextBoxBackColorを使えます。

たぶん、これが綺麗な解かと思いますが、どうでしょう?

「.config ファイルに内容が書かれる」というのも、
BackColorのSetでやればいいので、できなくは無いと思いますが、
できるかどうか調べる気になりません。
よしたほうがいいと思います。

[ メッセージ編集済み 編集者: れい 編集日時 2007-11-08 03:17 ]
こばさん
大ベテラン
会議室デビュー日: 2004/03/17
投稿数: 147
投稿日時: 2007-11-08 08:28
 確かに「無茶を言ってる」のは自覚してます。

 UserTextBox の中で「Me.DesignMode を見てデザイン中の時は config で設定された色を BackColor に代入するのをやめる(実行時のみ代入する)」とすれば、コントロールの貼り先で BackColor に関するコードが生成されないで済みますが、デザイン中には意図した BackColor で見ることができない・・・
 デザイン中に BackColor を変更すると、その変更結果で貼り先にコード生成されてしまう。そこんところがジレンマです。

 「既定値(定数しか指定できない)と異なったらコードを作成する」というIDEの単純な判断ロジックが気に入らないデス・・
 「IDEのプロパティウィンドウの値を触らなければ(触ってしまっても内容を消せば)コードは生成しない」というのが嬉しいのに・・・


 では、UserTextBox の背景色を「原則的には config ファイル値にするものの、そのコントロールの貼り先によっては指定色(configファイル値より優先する色)にする、という動作のユーザーコントロールを作ろうとした場合、どんな方法が最も美しい(スマート)と思いますか?
 別プロパティを公開するようにして、その辺を使ってやりくりしないといけないですかね??


※ 貼り先に無駄なコードが出来ることを許容すれば、さらにそれを上書きするなど無理にでもコーディングすれば実現できるのは確かなのですが、納期に余裕のあるうちはコーディングに美しさを追求したい・・・
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2007-11-08 09:20
引用:

 別プロパティを公開するようにして、その辺を使ってやりくりしないといけないですかね??



デザインでは無理でしょう。
やるとしたら
Public Sub New(defaultColor As Color)
InitializeComponent()
configからの設定
MyBase.Text1.BackColor = defaultColor
End Sub
くらいです。

引用:

※ 貼り先に無駄なコードが出来ることを許容すれば、さらにそれを上書きするなど無理にでもコーディングすれば実現できるのは確かなのですが、納期に余裕のあるうちはコーディングに美しさを追求したい・・・



隠蔽されるdesigner.vbに美しさを求めるのは無意味です。
またそこに独自のコードを入れようとするなら危険ですしやめたほうがいいでしょう。
まぁまずは「無駄」という大げさな思いを断ち切ることです。
元々全プロパティの代入文が生成されても不思議ではないのですから。

あと、値を外部ファイルに出したという意味について考えてください。
それは決まりを作ったということで、通常、利用者は独自に変更するなといっているのと同意だと思います。
それに対して独自の値を使用したいというのであれば、利用者側に独自値を代入するコードが出てきても何ら不自然さはありません。
#やらなければならないことをやっているのだから。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-11-08 09:53
引用:

こばさんさんの書き込み (2007-11-08 08:28) より:

「IDEのプロパティウィンドウの値を触らなければ(触ってしまっても内容を消せば)コードは生成しない」というのが嬉しいのに・・・


そのための DefaultValue 属性 + 値のクリア Command がセットになっています。 クリアすればコードは消え去ります。 ですので、どのあたりがご不満なのか理解できていないのですが、理解できていないのは私だけでしょうか? > 諸氏

引用:

「既定値(定数しか指定できない)と異なったらコードを作成する」というIDEの単純な判断ロジックが気に入らないデス・・
(snip)
別プロパティを公開するようにして、その辺を使ってやりくりしないといけないですかね??


どうもコードが生成されることが (直接的に) 気に入らないというわけではなさそうですね。 コードが生成されてしまうことで困るのは副次的な作用のあるプロパティで初期値の実装に手を加える場合くらいでしょうか。 ただ 「既定値」 自体に罪があるとは思えないですね。

引用:

※ 貼り先に無駄なコードが出来ることを許容すれば、さらにそれを上書きするなど無理にでもコーディングすれば実現できるのは確かなのですが、納期に余裕のあるうちはコーディングに美しさを追求したい・・・


あれ? やはり見た目を気にしているのでしょうか...? こばさんにとっての "美しい" とは何を示していますか? 私にとって美しいとは 「可読性が良い」「保守性が良い」 などです。 「既定値」 の動作を普通でなくすることは、むしろ 「醜い」 と感じます。

ただ 「初期値」 に柔軟性を求めることには反対しません。 あくまでも 「既定値」 です。

引用:

れいさんの書き込み (2007-11-08 03:13) より:

_backcolor=Color.Emptyの場合、
BackColorプロパティはMy.MySettings.Default.TextBoxBackColorを返すので、
My.MySettings.Default.TextBoxBackColorに規定値を設定しておけば


Code Generator 側でこのあたりが考慮されるかどうかまでは私にもわかりませんが、その発想はなかったですね...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
こばさん
大ベテラン
会議室デビュー日: 2004/03/17
投稿数: 147
投稿日時: 2007-11-08 11:03
 みなさま、どうもありがとうございました。
 自分自身、求める方向性がズレていることは理解してます。

 私の考える「美しさとは何か?」という話になってしまいますね。
 それだと某無能元首相と同じか・・?(笑)

 ユーザーコントロールの中身は可読性を犠牲(高スキルの人にしか読めない)にしても、貼った先でキレイに振舞うことをヨシとしてます。
 ユーザーコントロールを利用する人(≠ユーザーコントロールの作者)に、あまり負担をかけないように・・・と。

 例えば、基本仕様で「テキストボックスの背景色は原則として同一色にする。具体的に何色にするかは別途ファイル定義しておく」とある場合、基本仕様を満たす TextBox を予め用意しておいて、テキストボックスを使う時は標準の TextBox を使わずに、基本仕様を満たす UserTextBox を使う。

 UserTextBox を使う人(フォームに貼る人)は、UserTextBox を使う限り基本仕様は自動的に適用されていると見なして、基本仕様に関する部分には関わらない。
 原則から外れる個別条件だけ(ここだけは黄色で固定とか)面倒みる、と。

 実際には背景色だけでなくフォント名やサイズなど多岐にわたりますけどね。

 れいさんの書かれた ShouldSerializeXXX とかそういう系を駆使すれば、何とか出来そうな気はしてきました。
 「IDE を騙す」という手口ですよね。そこまでやるかどうかは別にして・・・


 継承したコントロールを使うにあたり、その辺まで IDE が追いついてない感じは受けてますが仕方ないか。。
 多重継承がサポートされてないのは、IDE で表現困難だからだろうし・・・

 すみません、後半は愚痴になりました。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-11-08 11:32
引用:

こばさんさんの書き込み (2007-11-08 08:28) より:
 「既定値(定数しか指定できない)と異なったらコードを作成する」というIDEの単純な判断ロジックが気に入らないデス・・
 「IDEのプロパティウィンドウの値を触らなければ(触ってしまっても内容を消せば)コードは生成しない」というのが嬉しいのに・・・



あれ〜?
私、言ってることずれてますか?

『「既定値(定数しか指定できない)と異なったらコードを作成する」というIDEの単純な判断ロジック』を変更するためのShouldSerializeXXXで、
ResetXXXを組み合わせることで
『「IDEのプロパティウィンドウの値を触らなければ(触ってしまっても内容を消せば)コードは生成しない」』
これを実現してるんですが。

ShouldSerializeXXXって、直訳すると
「XXXを記録するべきか」って意味にですよ。
コードを生成するかどうかと同義ですよ。

引用:

 では、UserTextBox の背景色を「原則的には config ファイル値にするものの、そのコントロールの貼り先によっては指定色(configファイル値より優先する色)にする、という動作のユーザーコントロールを作ろうとした場合、どんな方法が最も美しい(スマート)と思いますか?
 別プロパティを公開するようにして、その辺を使ってやりくりしないといけないですかね??



別プロパティだとプロパティの数が膨大になってしまうので
そういったことをするためにShouldSerializeがあるのでは?

引用:

 れいさんの書かれた ShouldSerializeXXX とかそういう系を駆使すれば、何とか出来そうな気はしてきました。
 「IDE を騙す」という手口ですよね。そこまでやるかどうかは別にして・・・



なんで「騙す」になるのかわからないです。
こうやって使うための特別なメソッドなんだし、
そう使えってMSDNにもあるし。

「騙す」っていう場合、普通もっとすごいことしますよ。
リフレクションつかったり、DLLインジェクションしたり。

引用:

まどかさんの書き込み:
デザインでは無理でしょう。
やるとしたら



??
どうして?
ShouldSerializeでできるのでは?

引用:

じゃんぬさんの書き込み:
Code Generator 側でこのあたりが考慮されるかどうかまでは私にもわかりませんが、その発想はなかったですね...



えっと??考慮されるとは?
文字通りそのまんま、
ShouldSerializeXXXがtrueならXXXがCode Generatorでシリアル可され、
falseならされませんよね?

あれれ?
なんかまた私だけずれてますか?
こばさんの言ってることも他の人の言ってることも
自分は理解してるつもりで、適切な回答してるつもりなんですが。

昔こばさんのやりたいこととほぼ同じことがやりたくて、
これで解決したんですがねぇ。

理解力が足りないっぽいですね。
暇ならだれか私に分かるように説明してくれるとうれしいっす。

[ メッセージ編集済み 編集者: れい 編集日時 2007-11-08 11:47 ]
こばさん
大ベテラン
会議室デビュー日: 2004/03/17
投稿数: 147
投稿日時: 2007-11-08 11:53
 れいさん、申し訳ありません。

 実は、れいさんの 投稿日時: 2007-11-08 03:13 の書き込みを読まずに、その次の「返答」をポストしてしまってたんです。
 このスレッドに「次のページ」が現れていることに気が付かず・・・

 ですので、ちょっとチグハグになっています。
 明記すべきでした。ごめんなさい。

 「IDE を騙す」は言葉良くないですね。
 「Code Generator を騙す・・・」じゃなくて、ちょっと強引な手口を使ってでも意図した動作になるよう矯正する、が正しいか。

 私の過去の遍歴が アセンブラ → C++(DOS時代) → VB(Windows時代) と来てますので、IDE 云々というより Code Generator が理解しきれていない面が大きいですね。
 ちょっと動きがお節介だけど、無いよりは便利〜 という感じか。

 Serialize 関係を触ると読める人間が極端に減っちゃう(少なくとも自分の周りでは)ので、最後の技と思っていたのですが、やはり最後はそこに行き着くわけですか。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-11-08 12:22
引用:

こばさんさんの書き込み (2007-11-08 11:53) より:
 「IDE を騙す」は言葉良くないですね。
 「Code Generator を騙す・・・」じゃなくて、ちょっと強引な手口を使ってでも意図した動作になるよう矯正する、が正しいか。



強引ですか。
そう思ったことはないですが…。

DefaultValueは定数しか使えないんで、
定数以外の規定値が欲しい時、
いつもこれを使います。

親と同じ値を使いたかったり、
他のプロパティと同じ値を使いたかったり、
そーゆー規定値が定数だとこまるプロパティはたくさんあって、
その時にはこれしかないですし。

とくに他人に公開するコントロールなんかは使い勝手が気になりますから、
DefaultValueAttribute
AmbientValueAttribute
ShouldSerializeXXX
ResetXXX
の4つをかなり使います。

むー。
強引、かなぁ?

引用:

 Serialize 関係を触ると読める人間が極端に減っちゃう(少なくとも自分の周りでは)ので、最後の技と思っていたのですが、やはり最後はそこに行き着くわけですか。



DefaultValueがだめならShouldSerializeなのでまだ2番目です。
それでもダメなときはデザイナ弄る手がありますので、最後ではないです。

何が難しいか人によって違うんでよくわかりませんが、
ただの関数を二ついじってやればいいだけなので
読める人が減るほど難しいとは思わなかったんですが、
私も今後気をつけないといけません。

[ メッセージ編集済み 編集者: れい 編集日時 2007-11-08 12:25 ]

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