Nullableのデザイン時のエラー

解決


へなちょこ  2006-09-26 06:05:52  No: 96715

VB.NET2005です。

テキストボックスを継承して作成したコントロールに
Nullable(Of Decimal) 型のプロパティを追加しました。
そのコントロールをフォームに貼り付け、
追加したプロパティに値をセットしたところ
次回以降のデザイナでのフォーム表示時に

「メソッド 'System.Nullable`1.op_Implicit' が見つかりません。」

というエラーが発生してしまいます。
警告なので実行は出来るのですが・・・

どうかご教示下さい。

追加したプロパティ
    Public Property Value() As Nullable(Of Decimal)
        Get
            Return _Value
        End Get
        Set(ByVal value As Nullable(Of Decimal))
            _Value = value
        End Set
    End Property


魔界の仮面弁士  2006-09-26 19:27:45  No: 96716

Nullable(Of Decimal) なコントロールを作ろうとしてハマる人は、結構いるようで。(^^;
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=489781&SiteID=7

たとえば「空欄」「1.234」という値を指定した場合に、自動生成されるDesignerコードが
  Me.NullableNumericBox1.Value = Nothing
  Me.NullableNumericBox2.Value = New Nullable(Of Decimal)(1.234D)
となってくれれば良いのですが、そのままの実装では、
  Me.NullableNumericBox1.Value = Nothing
  Me.NullableNumericBox2.Value = New Decimal(New Integer() {1234, 0, 0, 196608})
のようなコードになってしまうからのようですね。
エラーの出たデザイナコードを、手動で直接上記のように変更すれば開けると思います。

また、デザイン時には Nothing のみを指定するようにして、実際の値は
Form1_Load 等でValue プロパティを設定するようにすればエラーになりません。

で、とりあえず逃げの案としては、Value As Nullable(Of Decimal) に対する
標準のシリアライザを用いず、別の部分に永続化処理を組み込むといった方法があります。
http://www.vb-user.net/junk/replySamples/2006.09.26.10.06/Nullable.txt

# 上記では、入力検証や MyBase.Modified の制御などは省略しています。


へなちょこ  2006-09-26 20:16:06  No: 96717

返信ありがとうございます。
デザイナコードを変更するのはできました。
しかし、Public Property Value() As Nullable(Of Short)
には上手くいかなくてIntegerに変更して逃げました。

それから永続化処理ですがこれはなんのことやらわかりません。
もう少しロジックを眺めて検討してみます。

Nullableは無理して使わなくても代用でStringでも大丈夫なものなでしょうか?
値が入っていたらというのがHasValueで取れるからNullableの方が
便利なような気もしますが・・・


魔界の仮面弁士  2006-09-26 22:22:42  No: 96718

> しかし、Public Property Value() As Nullable(Of Short)
> には上手くいかなくてIntegerに変更して逃げました。

Short の場合は、
  〜.Value = CType(1234, Short)
となっている部分を、
  〜.Value = New Nullable(Of Short)(CType(1234, Short))
もしくは
  〜.Value = New Nullable(Of Short)(1234S)
などと書き換えてやれば良いでしょう。

# ちなみに、1234S の "S" は Short型のリテラルである事を示します。
# 1234D なら Decimal、1234US なら UShort、1234I なら Integer の意味です。

> それから永続化処理ですがこれはなんのことやらわかりません。

先のサンプルでは、Nullable(Of Decimal) の値を保存させるかわりに、
String 型を用いるようにしています。

これは、Value プロパティを「Designerに保存しないプロパティ」、
Text プロパティを「Designerに保存されるが、非表示のプロパティ」
と指定する事で実現させています。
つまり、Text プロパティを Value プロパティの代用にしているという事です。

具体的には、Designer.vb に保存されるかどうかを決定するために、
プロパティ定義に DesignerSerializationVisibility 属性を加えています。

そして、Textプロパティの方は、デザイナ上で非表示にしておくために、
Browsable 属性を付加し、かつ、コードエディタ上でも見えなくするため、
EditorBrowsable 属性を追加しています。

> Nullableは無理して使わなくても代用でStringでも大丈夫なものなでしょうか?

その場合、値を利用する側は、本当に数値化できるテキストかどうかを判断するために、
Decimal.TryParse などの併用が必要になってしまうかと思います。
(HasValue については、String.IsNullEmpty() で判断できるでしょう)

もし、String 型プロパティとして公開するのであれば、値を取得できるよう、
  Function GetValue() As Nullable(Of Decimal)
のような「メソッド」を用意しておくと、利用側の苦労が減るかもしれません。
# ついでに、設定用のメソッドもセットで追加するとか。


へなちょこ  2006-09-27 01:25:31  No: 96719

返信ありがとうございます。
色々と検討してみましたが
一番修正が少ないデザイナコードの修正に逃げました。

本当にありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加