DOBON.NET DOBON.NETプログラミング掲示板過去ログ

テキストボックスに独自のプロパティを追加

環境/言語:[WinXP VB.NET2005]
分類:[.NET]

お世話になります
WinXP、VB.NET2005と言う環境です
テキストボックスに独自のプロパティを作成したいと思っています

プロパティではTrueかFalseを設定する事で
例えばMaxByteLengthを6に設定した場合、12345と入力されたら
012345とテキストボックスに入る様にしたです
下記の様に記述しています
Public Property ZERO_FORMAT() As Boolean
Get
Return True
End Get
Set(ByVal value As Boolean)
If value = True Then
MyBase.Text = CStr(MyBase.Text).PadLeft(MyBase.MaxLength, "0"c)
End If
End Set
End Property
現在は、プロパティを追加出来たまでは良いのですが、プロパティをFalseにしてもTrueのままだったり、5と入れても000005とならず5のままになってしまっています。
アドバイスよろしくお願いします
■No23780に返信(まいかさんの記事)
> プロパティをFalseにしてもTrueのままだったり、
そりゃまぁ、常に True しか返さない仕様で書かれていますし。
> Get
>  Return True
> End Get


> 5と入れても000005とならず5のままになってしまっています。
000005 にするための処理を、どこに入れていますか?

提示されたコードには、「ZERO_FORMAT プロパティに値をセットした時」に
その処理が走るようになっていますよね。それと同じ処理を、
「ユーザーが入力した後」や「Text プロパティをセットされた時」にも
行っていますか?
魔界の仮面弁士さん、ありがとうございます
>000005 にするための処理を、どこに入れていますか?
Set(ByVal value As Boolean)のvalueがtrueの時です

>「ユーザーが入力した後」や「Text プロパティをセットされた時」にも
>行っていますか?
いいえ、貼り付けたコードが全てで、ユーザーが入力した後やText プロパティをセットされた時には全く記述していません
■No23782に返信(まいかさんの記事)
■No23782に返信(まいかさんの記事)
> Set(ByVal value As Boolean)のvalueがtrueの時です
> 貼り付けたコードが全てで、ユーザーが入力した後やText プロパティをセットされた時には全く記述していません

現在の実装だと、デザイン時に「False から True に変更した瞬間」には "000005" に変化するはずですが、今は True 固定なコードになっているため、フォーマット処理が動作しないわけです。


現在の実装であっても、プログラムからセットするのであれば、「True から True に変更」であってもフォーマットされますが、セットした瞬間にしか動作しないようなコードになっています。
 Private Sub Button1_Click(…
  SampleTextBox1.MaxLength = 6
  SampleTextBox1.Text = "5"
  SampleTextBox1.ZERO_FORMAT = True  'Text をセットした後で、True にすれば
  MsgBox(SampleTextBox1.Text)     '"000005" にフォーマットされる。
 End Sub
は、
 Private Sub Button2_Click(…
  SampleTextBox1.MaxLength = 6
  SampleTextBox1.ZERO_FORMAT = True
  SampleTextBox1.Text = "5"      'True にしてから Text をセットした場合は、
  MsgBox(SampleTextBox1.Text)     '"5" のままとなり、フォーマットされない。
 End Sub


なのでこれらの場合にも正しくフォーマットされるようにするために、例えば、OnTextChanged メソッド、OnLeave メソッド、OnMaxLengthChanged メソッドなどをオーバーライドするなどといった対処が求められるかと思います。
(Text/OnTextChanged を処理する時は、変更処理が連鎖しないように注意…)
魔界の仮面弁士さんありがとうございます
色々サイトを見つつ、試しています
現在は下記記述の様にしています。
    Private b_ZERO As Boolean = False

    Public Property ZERO_FORMAT() As Boolean
        Get
            Return b_ZERO
        End Get
        Set(ByVal value As Boolean)
            b_ZERO = value

            If b_ZERO = True Then
                MyBase.Text = CStr(MyBase.Text).PadLeft(MyBase.MaxLength, "0"c)
            End If
        End Set
    End Property
「ユーザーが入力した後」は同クラス内のイベントでValidatingを発生させていますが、
「Text プロパティをセットされた時」はどんなイベントを発生させて上げれば良いのでしょうか
よろしくお願いします
■No23784に返信(まいかさんの記事)
> Public Property ZERO_FORMAT() As Boolean
必須ではありませんが、DefaultValueAttribute の属性をセットしておいた方が良いですよ。
プロパティのリセットが行えるようになりますし、自動生成コードにの縮小にも繋がります。
http://www.microsoft.com/japan/msdn/thisweek/10lines/vs2005/winform_usercontrol/vb.aspx

<DefaultValue(False)> _
Public Property ZERO_FORMAT() As Boolean


> If b_ZERO = True Then
False に戻した時に、"0" を取り除く処理は無くて良いのですね?


> 「ユーザーが入力した後」は
「MaxLength プロパティを変更された時」などにも必要かと思います。他にもあるかも?


> Validatingを発生させていますが、
OnValidating のプロテクトメソッドを呼び出している、という意味でしょうか。
それとも、独自に Validating という名のシャドウ イベントを作っているという事でしょうか。


> 「Text プロパティをセットされた時」は
先の回答にも少し書きましたが、
 案1) OnTextChanged メソッドをオーバーライドする。
 案2) Text プロパティをオーバーライドする。
といった対応が考えられます。


> どんなイベントを発生させて上げれば良いのでしょうか
コンポーネント側では自身のイベントを利用しないでください。

http://msdn.microsoft.com/ja-jp/library/3b8tbfec.aspx
》コントロールが発生させたプロパティ変更イベントへ
》このコントロール自体が応答する必要がある場合には、
》デリゲートをイベントへアタッチする代わりに、
》対応する On[PropertyName]Changed メソッドをオーバーライドします。



それともう一点。Modified プロパティにも注意してください。

ユーザーが入力した場合、Modified は自動的に True になりますが、今回のように
プログラムから Text プロパティをセットした場合、その時点で Modified が
False になってしまいます。ですから、"5" を "000005" に書き替える際には、

 MyBase.Text = CStr(MyBase.Text).PadLeft(MyBase.MaxLength, "0"c)

ではなく、

 Dim oldModified As Boolean = MyBase.Modified
 MyBase.Text = CStr(MyBase.Text).PadLeft(MyBase.MaxLength, "0"c)
 MyBase.Modified = oldModified

のようにして、Modified 値が書き変わらないように考慮する必要があります。
魔界の仮面弁士さんありがとうございます
> OnValidating のプロテクトメソッドを呼び出している、という意味でしょうか。
> それとも、独自に Validating という名のシャドウ イベントを作っているという事でしょうか。
クラスのイベントからValidatingを生成していました。
Protected Overrides Sub OnValidating(…)を作ってみました

フォームからテキストボックスに入力した際に
MaxByteLengthを6に設定した場合、12345と入力されたら012345とテキストボックスに出れば良いので
Public Property ZERO_FORMAT() As BooleanにあったIf文を消して
Protected Overrides Sub OnValidatingに移動して
        MyBase.OnValidating(e)
        If b_ZERO = True Then
            MyBase.Text = CStr(MyBase.Text).PadLeft(MyBase.MaxLength, "0"c)
        End If
        Invalidate()
としました。
一応私の希望の動作になったので、解決済みにさせて頂きます
ありがとうございました
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板