'System.Design を参照設定に追加
Imports System.ComponentModel
Imports System.Web.UI
'Namespace MyWebControls
#Region " PostBackValidatorコントロール "
''' <summary>
''' ラウンドトリップの妥当性を検証する Web サーバーコントロール
''' </summary>
<DefaultProperty("ErrorMessage"), _
Designer(GetType(MyWebControls.PostBackValidatorDesigner)), _
ToolboxData("<{0}:PostBackValidator runat=server></{0}:PostBackValidator>")> _
Public Class PostBackValidator
Inherits System.Web.UI.WebControls.Label
Implements System.Web.UI.IValidator
#Region " メンバ変数宣言 "
Friend _IsValid As Boolean = True
Private _Display As System.Web.UI.WebControls.ValidatorDisplay = _
System.Web.UI.WebControls.ValidatorDisplay.Static
Private _ErrorMessage As String = String.Empty
Private CounterKey As String
#End Region
#Region " コンストラクタ "
''' <summary>PostBackValidator クラスの新しいインスタンスを初期化</summary>
Public Sub New()
MyBase.New()
Me.ForeColor = Drawing.Color.Red
MyBase.EnableViewState = True
End Sub
#End Region
#Region " プロパティ "
''' <summary>ラウンドトリップの整合性の検証が成功したかどうかを示す値を取得、または設定</summary>
<Browsable(False)> _
Public Property IsValid() As Boolean Implements System.Web.UI.IValidator.IsValid
Get
Return _IsValid
End Get
Set(ByVal Value As Boolean)
_IsValid = Value
If Value Then
Me.Reset()
End If
End Set
End Property
''' <summary>
''' 検証コントロールにエラーメッセージを表示する際の動作を表す
''' System.Web.UI.WebControls.ValidatorDisplay の値を取得、または設定
''' </summary>
<Description("検証コントロールにエラーメッセージを表示する際の動作"), _
Category("Appearance"), _
DefaultValue(GetType(System.Web.UI.WebControls.ValidatorDisplay), "Static")> _
Public Property Display() As System.Web.UI.WebControls.ValidatorDisplay
Get
Return _Display
End Get
Set(ByVal Value As System.Web.UI.WebControls.ValidatorDisplay)
_Display = Value
End Set
End Property
''' <summary>前景色を表す System.Drawing.Color の値を取得または設定</summary>
<Description("前景色"), _
Category("Appearance"), _
DefaultValue(GetType(System.Drawing.Color), "Red")> _
Public Overrides Property ForeColor() As System.Drawing.Color
Get
Return MyBase.ForeColor
End Get
Set(ByVal Value As System.Drawing.Color)
MyBase.ForeColor = Value
End Set
End Property
''' <summary>エラーメッセージのテキストを取得、または設定</summary>
<Description("エラーメッセージのテキスト"), _
Category("Appearance")> _
Public Property ErrorMessage() As String Implements System.Web.UI.IValidator.ErrorMessage
Get
Return _ErrorMessage
End Get
Set(ByVal Value As String)
_ErrorMessage = Value
End Set
End Property
' 隠蔽(動作上必要だが弄られたくない)
<Browsable(False), _
EditorBrowsable(EditorBrowsableState.Never), _
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Overrides Property Text() As String
Get
If (Not _IsValid) And (Not _Display.Equals(System.Web.UI.WebControls.ValidatorDisplay.None)) Then
Return Me.ErrorMessage
Else
Return MyBase.Text
End If
End Get
Set(ByVal Value As String)
MyBase.Text = Value
End Set
End Property
' 隠蔽(動作上必要だが弄られたくない)
<Browsable(False), _
EditorBrowsable(EditorBrowsableState.Never), _
DesignOnly(True), _
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Shadows ReadOnly Property EnableViewState() As Boolean
Get
Return True
End Get
End Property
#End Region
#Region " メソッド "
'// PostBackValidator.Init イベントハンドラ
Private Sub PostBackValidator_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Init
CounterKey &= Me.ID
CounterKey &= "_PostbackCounter"
End Sub
''' <summary>
''' 検証を実行し、IsValid プロパティを更新
''' </summary>
Public Sub Validate() Implements System.Web.UI.IValidator.Validate
If Me.Enabled Then
Dim ClientCounter, ServerCounter As Double
If Page.IsPostBack Then
'// カウンタ値取得
ServerCounter = CType(Page.Session(CounterKey), Double)
ClientCounter = CType(ViewState(CounterKey), Double)
Else
If CType(Page.Session(CounterKey), Double).Equals(0.0#) Then
'// セッションに値が保持されていない場合、本当の最初の要
'// 求と見なしてカウンタ値を初期化
ServerCounter = Microsoft.VisualBasic.DateAndTime.Timer
ClientCounter = ServerCounter
Else
'// ブラウザの戻るボタンで GET 要求が走る場合があるので
'// クライアント側のカウンタだけを更新
ClientCounter = Microsoft.VisualBasic.DateAndTime.Timer
End If
End If
If ServerCounter.Equals(ClientCounter) Then
'// カウンタ値が一致した場合、双方のカウンタを更新
ServerCounter = Microsoft.VisualBasic.DateAndTime.Timer
ClientCounter = ServerCounter
Page.Session.Add(CounterKey, ServerCounter)
ViewState.Add(CounterKey, ClientCounter)
Else
'// 一致しない場合、不整合と見なす
_IsValid = False
End If
End If
End Sub
''' <summary>監視状態をリセット</summary>
Public Overridable Sub Reset()
_IsValid = True
ViewState.Remove(CounterKey)
Page.Session.Remove(CounterKey)
End Sub
''' <summary>PostBackValidator.Init イベント</summary>
''' <param name="e">イベント データを格納している System.EventArgs オブジェクト</param>
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
Page.Validators.Add(Me)
End Sub
''' <summary>PostBackValidator.Load イベント</summary>
''' <param name="e">イベント データを格納している System.EventArgs オブジェクト</param>
Protected Overrides Sub OnUnload(ByVal e As System.EventArgs)
If Not (Page Is Nothing) Then
Page.Validators.Remove(Me)
End If
MyBase.OnUnload(e)
End Sub
''' <summary>保存された前回のページ要求からビューステート情報を復元</summary>
''' <param name="savedState">復元するデータを保持する System.Object</param>
Protected Overrides Sub LoadViewState(ByVal savedState As Object)
If Not savedState Is Nothing Then
Dim CustomState As Object() = CType(savedState, Object())
If (Not CustomState(0) Is Nothing) Then
MyBase.LoadViewState(CustomState(0))
End If
If (Not CustomState(1) Is Nothing) Then
_ErrorMessage = CustomState(1)
End If
If (Not CustomState(2) Is Nothing) Then
_Display = CustomState(2)
End If
End If
End Sub
''' <summary>サーバー コントロールのビューステートの変更を保存</summary>
''' <returns>サーバー コントロールの現在のビューステート</returns>
Protected Overrides Function SaveViewState() As Object
Dim CustomState As System.Collections.ArrayList = New System.Collections.ArrayList
CustomState.Add(MyBase.SaveViewState)
CustomState.Add(_ErrorMessage)
CustomState.Add(_Display)
Return CustomState.ToArray()
End Function
#End Region
End Class
#End Region
#Region " PostBackValidatorコントロールデザイナ "
''' <summary>MyWebControls.PostBackValidator Web サーバー コントロールのデザイン時の動作を拡張</summary>
Public Class PostBackValidatorDesigner
Inherits System.Web.UI.Design.TextControlDesigner
''' <summary>デザイン時に関連付けられたコントロールを表示するために使用する HTML を取得</summary>
''' <returns>デザイン時にコントロールを表示するための HTML</returns>
Public Overrides Function GetDesignTimeHtml() As String
Dim Ctrl As MyWebControls.PostBackValidator = CType(Me.Component, MyWebControls.PostBackValidator)
Dim Visible As Boolean = Ctrl.Visible
If Ctrl.Display.Equals(System.Web.UI.WebControls.ValidatorDisplay.None) _
OrElse Ctrl.ErrorMessage.Length.Equals(0) Then
Return MyBase.GetDesignTimeHtml()
Else
Dim Sw As System.IO.StringWriter = New System.IO.StringWriter
Dim Htw As HtmlTextWriter = New HtmlTextWriter(Sw)
Ctrl._IsValid = False
Ctrl.Visible = True
Ctrl.RenderControl(Htw)
Ctrl._IsValid = True
Ctrl.Visible = Visible
Return Sw.ToString()
End If
End Function
End Class
#End Region
'End Namespace
|