none
カスタムコントロールでValidatingを補完するイベントを作成するには? RRS feed

  • 質問

  • こんにちは、Deer327です。
    この質問はフィードバックフォーラムの「Validatingの不可解なふるまい」から
    移動したものです。

    質問の趣旨は、FormClosingで発生するValidatingイベント内処理を
    スルーさせるコードを、自作のValidatingイベントにて
    実装する方法についてです。

     じゃんぬねっと さんからの引用

    Validating イベントでは面倒ということであれば、この条件を満たす自作の MyValidating イベントを作ると良いです。
    この場合のコントロールは、カスタム コントロールになります。

    クラスの知識が乏しく、これがよく分かりません。
    現状をご説明しますので、アドバイス頂けたら助かります。

    Form1
     Txt_ShohinCode(MyTextBoxコントロール)を配置
     Txt_ShohinName(ラベルコントロール)を配置
     Txt_Suryo(MyTextBoxコントロール)を配置

    MyTextBox(TextBoxクラスを継承したカスタムコントロール)の概要
     OnValidatingメソッド
      1.自分がアクティブなら、このイベントをスルーする。
      2.入力値の検証を行う

    Txt_ShohinCodeの概要
     Validatingイベントハンドラ
      1.自分がアクティブなら、このイベントをスルーする。
      2.商品テーブルを読み込み、商品名をTxt_ShohinNameにセットする。

    Txt_Suryoの概要
     Validatingイベントハンドラ ※不要

    Txt_ShohinCodeのようにカスタムコントロールの検証後、
    引き続き何らかの処理を行う場合、Validatingイベントハンドラにおいて、
    「自分がアクティブなら、このイベントをスルーする。」処理が必要となり、
    コードが冗長になります。
    『~この条件を満たす自作の MyValidating イベントを作る』
    との提言がこの解決策になるという事ですが、
    実装方法のヒントなど頂けたらありがたいです。

    2006年8月30日 7:32

回答

  • では、次にイベントを定義してください。


    Public Event MyValidating As System.ComponentModel.CancelEventHandler
     

    あとは、OnValidating メソッドをオーバーライドして、
    しかるべき条件の下で Raise してください。

    2006年8月30日 9:43
  • Deer327 さん、こんにちは。

     Deer327 さんからの引用
    情報共有という事で、簡単ですがご報告いたします。

    情報共有のためのフィードバック、ありがとうございます。(*_ _)

    基底クラスへの MyBase.OnValidating メソッドへの呼び出しは、
    握りつぶさない方が、カスタム コントロール的に美しいと思います。

    Validating はそのままの実装で、MyValidating の方で代用するという形が望ましいです。

    カスタム コントロールもクラス ライブラリ設計に含まれますから、
    利用者側が予想できるように、既存のメンバの機能を変えないようにするのが望ましいです。

    2006年8月31日 0:00

すべての返信

  • まず、System.Windows.Forms.TextBox を継承したコントロールは作成済みでしょうか?


    Public Class MyTextBox : Inherits System.Windows.Forms.TextBox

    End Class

     

    2006年8月30日 8:16
  • じゃんぬねっとさん、さっそくありがとうございます。

     じゃんぬねっと さんからの引用

    まず、System.Windows.Forms.TextBox を継承したコントロールは作成済みでしょうか?

    はい、以下のようなコントロールを作成してあります。

    Imports System.ComponentModel
    Public Class MyTextBox
        Inherits System.Windows.Forms.TextBox

    実装しているメソッド(プロパティは省略)

        Protected Overrides Sub OnValidating(...
          1.フラグでスルー
          2.値の検証

        Protected Overrides Sub OnLeave(...
          1.フラグのセット

        Protected Overrides Sub OnEnter(...
          1.前方向遷移でこの項目をスキップ
          2.文字列を反転

        Protected Overrides Sub OnKeyPress(...
          1.次の項目へ移動

        Private Sub MyTextBox_ReadOnlyChanged(...
          1.連動してTabStopを切替え
    End Class

    2006年8月30日 8:48
  • では、次にイベントを定義してください。


    Public Event MyValidating As System.ComponentModel.CancelEventHandler
     

    あとは、OnValidating メソッドをオーバーライドして、
    しかるべき条件の下で Raise してください。

    2006年8月30日 9:43
  • じゃんぬねっとさん、ご教示ありがとうございました。

    自作イベントで無事、動作確認できました。
    合わせて自作イベントなしでの動作も確認できました。
    今回はどちらでも同じようなものですが、
    他にも応用できる事を考慮すれば自作イベントに慣れた方が、良さそうですね。
    情報共有という事で、簡単ですがご報告いたします。

    ■OnValidating + MyValidating(自作イベント)の組み合わせ

    Public Class MyTextBox
        Inherits System.Windows.Forms.TextBox

        Protected Overrides Sub OnValidating(...
            自分がアクティブなら Exit Sub … [X]ボタンの対応
            フラグが立っていれば Exit Sub … キャンセル、終了ボタンの対応

            入力エラーなら e.Cancel = True
              でなければ RaiseEvent MyValidating(Me, e) … (1)

        Public Event MyValidating As System.ComponentModel.CancelEventHandler … (2)

    Public Class Form1
        Inherits System.Windows.Forms.Form

        Private Sub MyTextBox1_MyValidating(... … (3)
            入力エラーなら エラー表示 ~ e.Cancel = True

    ※通常のValidatingイベントを使用する場合
      (1)はMyBase.OnValidating(e)とする
      (2)は不要
      (3)はMyValidating -> Validatingとする

    今回の件で、VBが更におもしろくなってきました。

    2006年8月30日 13:40
  • Deer327 さん、こんにちは。

     Deer327 さんからの引用
    情報共有という事で、簡単ですがご報告いたします。

    情報共有のためのフィードバック、ありがとうございます。(*_ _)

    基底クラスへの MyBase.OnValidating メソッドへの呼び出しは、
    握りつぶさない方が、カスタム コントロール的に美しいと思います。

    Validating はそのままの実装で、MyValidating の方で代用するという形が望ましいです。

    カスタム コントロールもクラス ライブラリ設計に含まれますから、
    利用者側が予想できるように、既存のメンバの機能を変えないようにするのが望ましいです。

    2006年8月31日 0:00
  • じゃんぬねっとさん、こんにちは。

     じゃんぬねっと さんからの引用

    基底クラスへの MyBase.OnValidating メソッドへの呼び出しは、
    握りつぶさない方が、カスタム コントロール的に美しいと思います。

    なるほど!これは納得しました。
    この辺の指針がなかなか分からないもので...

    #うう、他にも不作法なところ、いっぱいあるんだろうな orz

     

    2006年8月31日 8:34
  • >>Deer327さん

     Deer327 さんからの引用
    この辺の指針がなかなか分からないもので...
    #うう、他にも不作法なところ、いっぱいあるんだろうな orz

    コントロールに限らず、このあたりは、クラス デザインの 「機能拡張」 のガイドラインに準ずれば良いと思います。

    コントロール独自のガイドラインは、まとめてあるページはなかなか見あたりませんね。
    Windows コントロールと Web サーバーコントロールとまたちょっと違うでしょうし...

    2006年8月31日 9:34
  •  じゃんぬねっと さんからの引用

    コントロールに限らず、このあたりは、クラス デザインの 「機能拡張」 のガイドラインに準ずれば良いと思います。

    了解です。
    いろいろ教えていただき、ありがとうございました。
    また何かありましたら、宜しくお願いいたします。

    2006年9月1日 1:07
  • 情報共有のためのフィードバックとのことなので、
    一応書き込みます。

    メニューやツールストリップボタンではActiveControlは切り替わりません。
    従ってこの方式ではValidatingがスルーされてしまいます、

    一旦Validatingは通ってからそのあとでクローズするのですが、
    Closing イベント(VisualStudio2003)/FormClosing イベント(VisualStudio2005)を使ってください。

    http://www.ailight.jp/blog/mnow/archive/2006/11/23/13345.aspx

    2006年11月23日 18:37