コンポジションとレンダリング
コンポジションを使用すると、複合コントロールを比較的簡単に作成できますが、子コントロールを作成する必要があるためにパフォーマンスのオーバーヘッドが生じます。コントロールのパフォーマンスを最適化するには、Render メソッドをオーバーライドして、レンダリング ロジックを実装します。さらに、コントロールに必要なポストバック データ処理とポストバック イベント処理を実装する必要もあります。
「複合サーバー コントロールのサンプル」に示されているのと同等のユーザー インターフェイスをレンダリングする Rendered
コントロールのサンプルを次に示します。Rendered
コントロールはコンポジションを使用しないため、作成方法はより複雑になります。
次に示す Rendered
のメンバは、「複合サーバー コントロールのサンプル」に示されているメンバと同一です。
Text
パブリック プロパティ。(このサンプルでは、このプロパティは子コントロールに渡されません)Number
パブリック プロパティ。Sum
プライベート プロパティ。Check
カスタム イベント。
Rendered
は子コントロールを持たないため、次の処理を実行する必要があります。
- テキスト ボックスの独自の実装を用意する。
- 送信ボタンの独自の実装を用意する。
- IPostBackEventHandler を実装する。
- IPostBackDataHandler を実装する。
- Render メソッドをオーバーライドする。
このサンプルでは状態を復元する必要がないため、Rendered
は、ラウンド トリップ時にプロパティを永続化するための ViewState を使用していません。また、Render メソッドが生 HTML を HtmlTextWriter の Write メソッドへ書き込むことにも注意してください。レンダリングにおける HtmlTextWriter のユーティリティ メソッドの使用例については、「サーバー コントロールのレンダリングのサンプル」を参照してください。
このサンプルをビルドする方法については、「サーバー コントロールのサンプル」の手順を参照してください。
using System;
using System.Web;
using System.Web.UI;
using System.Collections.Specialized;
namespace CustomControls
{
public class Rendered : Control, IPostBackDataHandler, IPostBackEventHandler
{
private String text1;
private String text2;
private String text = "Press the button to see if you won.";
private int number = 100;
private int Sum
{
get
{
return Int32.Parse(text1) +
Int32.Parse(text2);
}
}
public int Number
{
get
{
return number;
}
set
{
number = value;
}
}
public String Text {
get {
return text;
}
set {
text = value;
}
}
public event CheckEventHandler Check;
protected virtual void OnCheck(CheckEventArgs ce)
{
if (Check != null)
{
Check(this,ce);
}
}
public virtual bool LoadPostData(string postDataKey,
NameValueCollection values) {
text1 = values[UniqueID + "t1"];
text2 = values[UniqueID+ "t2"];
Page.RegisterRequiresRaiseEvent(this);
return false;
}
public virtual void RaisePostDataChangedEvent() {
}
public void RaisePostBackEvent(string eventArgument){
OnCheck(new CheckEventArgs(Sum - Number));
}
protected override void Render(HtmlTextWriter output) {
output.Write ("<h3>Enter a number : ");
output.Write("<INPUT type= text name = " + this.UniqueID + "t1" +
" value = '0' >");
output.Write("</h3><br>");
output.Write ("<br><h3>Enter another number : ");
output.Write("<INPUT type= text name = " + this.UniqueID + "t2" +
" value = '0' >");
output.Write("</h3><br>");
output.Write("<br><br><input type= submit name = " +
this.UniqueID + " value= 'Submit'>");
output.Write("<br><br><span style='height:50px;width:500px;'>"
+ Text + "</span>");
}
}
}
// CheckEvent.cs.
// Contains the code for the custom event data class CheckEventArgs.
// Also defines the event handler for the Check event.
using System;
namespace CustomControls
{
public class CheckEventArgs : EventArgs
{
private bool match = false;
public CheckEventArgs (int difference)
{
if (difference == 0)
{
match = true;
}
}
public bool Match
{
get
{
return match;
}
}
}
public delegate void CheckEventHandler(object sender, CheckEventArgs ce);
}
[Visual Basic]
Option Explicit
Option Strict
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Collections.Specialized
Namespace CustomControls
Public Class Rendered
Inherits Control
Implements IPostBackDataHandler, IPostBackEventHandler
Private text1 As String
Private text2 As String
Private _text As String = "Press enter to see if you won."
Private _number As Integer = 100
Private ReadOnly Property Sum() As Integer
Get
Return Int32.Parse(text1) + Int32.Parse(text2)
End Get
End Property
Public Property Number() As Integer
Get
Return _number
End Get
Set
_number = value
End Set
End Property
Public Property Text() As String
Get
Return _text
End Get
Set
_text = value
End Set
End Property
Public Event Check As CheckEventHandler
Protected Overridable Sub OnCheck(ce As CheckEventArgs)
RaiseEvent Check(Me, ce)
End Sub
Public Overridable Function LoadPostData(postDataKey As String, values As NameValueCollection) As Boolean Implements IPostBackDataHandler.LoadPostData
text1 = values(UniqueID & "t1")
text2 = values(UniqueID & "t2")
Page.RegisterRequiresRaiseEvent(Me)
Return False
End Function
Public Overridable Sub RaisePostDataChangedEvent() Implements IPostBackDataHandler.RaisePostDataChangedEvent
End Sub
Public Sub RaisePostBackEvent(eventArgument As String) Implements IPostBackEventHandler.RaisePostBackEvent
OnCheck(New CheckEventArgs(Sum - Number))
End Sub
Protected Overrides Sub Render(output As HtmlTextWriter)
output.Write("<h3>Enter a number : ")
output.Write("<INPUT type= text name = " & _
Me.UniqueID & "t1" & _
" value = '0' >")
output.Write("</h3><br>")
output.Write("<br><h3>Enter another number : ")
output.Write("<INPUT type= text name = " & _
Me.UniqueID & "t2" & _
" value = '0' >")
output.Write("</h3><br>")
output.Write("<br><br><input type= submit name = " & _
Me.UniqueID & _
" value= 'Submit'>")
output.Write("<br><br><span style='height:50px;width:500px;'>" & _
Text & "</span>")
End Sub
End Class
End Namespace
' CheckEvent.vb
' Contains the code for the custom event data class CheckEventArgs.
' Also defines the event handler for the Check event.
Imports System
Namespace CustomControls
Public Class CheckEventArgs
Inherits EventArgs
Private _match As Boolean = False
Public Sub New(difference As Integer)
If difference = 0 Then
_match = True
End If
End Sub
Public ReadOnly Property Match() As Boolean
Get
Return _match
End Get
End Property
End Class
Public Delegate Sub CheckEventHandler(sender As Object, ce As CheckEventArgs)
End Namespace
ページでのレンダリングされたコントロールの使用
前のサンプルで定義した Rendered
カスタム コントロールを使用するページの例を次に示します。このページは、レンダリングされたコントロールを複合コントロールの代わりに使用する点を除いては、「複合サーバー コントロールのサンプル」のページと同一です。
<%@ Register TagPrefix="Custom" Namespace="CustomControls" Assembly = "CustomControls" %>
<script language="VB" runat=server>
Private Sub Sum_Checked(sender As Object, e As CheckEventArgs)
If e.Match = True Then
Rendered.Text = "<h2> You won a million dollars!!!! </h2>"
Else
Rendered.Text = "Sorry, try again. The numbers you entered don't add up to" & _
" the hidden number."
End If
End Sub
</script>
<html>
<body>
<h1> The Mystery Sum Game </h1><br>
<form runat=server>
<Custom:Rendered id = "Rendered" OnCheck = "Sum_Checked" Number= "10" runat = server/>
</form>
</body>
</html>