共用方式為


保存非表單控制項的用戶端變更

用戶端 ECMAScript (JScript、JavaScript) 可以用來追蹤非表單項目控制項的用戶端狀態變更。這類控制項沒有經由表單送出將資料回傳給伺服器的管道。它可以執行事件回傳,但可能無法成功。這個問題可以使用隱藏輸入欄位來解決,它可以含有控制項的資料。控制項必須發出隱藏輸入欄位並發出指令碼,在送出表單之前將狀態資訊插入隱藏欄位。當載入控制項後,控制項即可擷取並使用隱藏欄位的資料。若要啟用這項機制,控制項可以叫用 PageRegisterHiddenField 方法,來發出隱藏欄位並實作 IPostBackDataHandler 介面以回復隱藏欄位的值並更新它的屬性。

以下範例就是示範這個案例。範例中的控制項 (DHtmlControl) 會發出一個範圍,當它被選取時即會於用戶端變更色彩。控制項會發出一個隱藏變數,由用戶端指令碼將它的值設為布林 (Boolean) 變數,以表示是否已選取該控制項。控制項會公開 Boolean 屬性 (Selected),表示是否已在用戶端上選取該控制項。控制項會實作 IPostBackDataHandler 介面,當網頁張貼至伺服器後,使控制項可以讀取隱藏欄位的值並更新its Selected 屬性。當已在用戶端上選取控制項時,控制項也會公開它所引發的事件 (SelectedChanged)。

若要建置範例,請參閱伺服器控制項範例中的說明。

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Drawing;
using System.Web;
using System.Web.UI;

namespace CustomControls
{
      public class DHtmlControl : Control, IPostBackDataHandler
      {
            public event EventHandler SelectedChanged;

            public string Text
            {
                  get
                  {
                        object obj = ViewState["Text"];
                        return (obj == null) ? String.Empty : (string)obj;
                  }

                  set
                  {
                        ViewState["Text"] = value;
                  }
            }

            public bool Selected
            {
                  get
                  {
                        object obj = ViewState["Selected"];
                        return (obj == null) ? false : (bool)obj;
                  }

                  set
                  {
                        ViewState["Selected"] = value;
                  }
            }

            protected string HelperID
            {
                  get
                  {
                        return "__" + ClientID + "_State";
                  }
            }

            protected override void OnInit(EventArgs e)
            {
                  base.OnInit(e);

                  if (Page != null)
                  {
                        Page.RegisterRequiresPostBack(this);
                  }
            }

            protected override void OnPreRender(EventArgs e)
            {
                  base.OnPreRender(e);

                  if (Page != null)
                  {
                        Page.RegisterHiddenField(HelperID, Selected.ToString());
                  }
            }

            protected override void Render(HtmlTextWriter writer)
            {
                  string postback = "";
                  if (Page != null)
                  {
                        postback = Page.GetPostBackEventReference(this) + ";";
                  }

                  string click = "onclick=\"var sel=getAttribute('selected'); sel = (sel.toLowerCase() == 'true'); sel=!sel; setAttribute('selected', sel.toString());this.style.backgroundColor=sel?'red':'white';" + HelperID +".value=sel.toString();" + postback + "\"";
                  string style = "style=\"cursor:hand;background-color:" + (Selected ? "red" : "white") + "\"";
                  string selected = "selected=\"" + Selected.ToString() + "\"";
                  writer.Write("<span " + style + " " + click + " " + selected + ">" + Text + "</span>");
            }

            bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
            {
                  string value = postCollection[HelperID];

                  if (value != null)
                  {
                        bool newValue = (String.Compare(value, "true", true) == 0);
                        bool oldValue = Selected;

                        Selected = newValue;

                        // If there is a change, raise a change event.
                        return (newValue != oldValue);
                  }

                  return false;
            }

            void IPostBackDataHandler.RaisePostDataChangedEvent()
            {
                  // There was a change,  so raise any events.
                  if (SelectedChanged != null)
                  {
                        SelectedChanged(this, EventArgs.Empty);
                  }
            }
      }
}
[Visual Basic]
Option Explicit
Option Strict

Imports System
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Drawing
Imports System.Web
Imports System.Web.UI
Imports Microsoft.VisualBasic

Namespace CustomControls
   Public Class DHtmlControl
      Inherits Control
      Implements IPostBackDataHandler
      Public Event SelectedChanged As EventHandler
      
      Public Property Text() As String
         Get
            Dim obj As Object = ViewState("Text")
            If obj Is Nothing Then
               Return String.Empty
            Else
               Return CStr(obj)
            End If
         End Get
         
         Set
            ViewState("Text") = value
         End Set
      End Property
      
      Public Property Selected() As Boolean
         Get
            Dim obj As Object = ViewState("Selected")
            If obj Is Nothing Then
               Return False
            Else
               Return CBool(obj)
            End If
         End Get
         
         Set
            ViewState("Selected") = value
         End Set
      End Property
      
      Protected ReadOnly Property HelperID() As String
         Get
            Return "__" & ClientID & "_State"
         End Get
      End Property
      
      Protected Overrides Sub OnInit(e As EventArgs)
         MyBase.OnInit(e)
         
         If Not (Page Is Nothing) Then
            Page.RegisterRequiresPostBack(Me)
         End If
      End Sub
      
      Protected Overrides Sub OnPreRender(e As EventArgs)
         MyBase.OnPreRender(e)
         
         If Not (Page Is Nothing) Then
            Page.RegisterHiddenField(HelperID, Selected.ToString())
         End If
      End Sub
      
      Protected Overrides Sub Render(writer As HtmlTextWriter)
         Dim postback As String = ""
         If Not (Page Is Nothing) Then
            postback = Page.GetPostBackEventReference(Me) & ";"
         End If
         
         Dim click As String = "onclick=""var sel=getAttribute('selected'); sel = (sel.toLowerCase() == 'true'); sel=!sel; setAttribute('selected', sel.toString());this.style.backgroundColor=sel?'red':'white';" & HelperID & ".value=sel.toString();" & postback & """"
         Dim style As String = "style=""cursor:hand;background-color:" & IIf(Selected, "red", "white").ToString() & """"
         Dim selectedPiece As String = "selected=""" & Selected.ToString() & """"
         writer.Write(("<span " & style & " " & click & " " & selectedPiece & ">" & Text & "</span>"))
      End Sub 
      
      Function LoadPostData(postDataKey As String, postCollection As NameValueCollection) As Boolean Implements IPostBackDataHandler.LoadPostData
         Dim value As String = postCollection(HelperID)
         
         If Not (value Is Nothing) Then
            Dim newValue As Boolean = String.Compare(value, "true", True) = 0
            Dim oldValue As Boolean = Selected
            
            Selected = newValue
            
            ' If there is a change, raise a change event.
            Return newValue <> oldValue
         End If
         
         Return False
      End Function
      
      Sub RaisePostDataChangedEvent() Implements IPostBackDataHandler.RaisePostDataChangedEvent
         ' There was a change, so raise any events.
         RaiseEvent SelectedChanged(Me, EventArgs.Empty)
      End Sub
   End Class 
End Namespace

使用 DHTML 控制項的網頁

下列網頁將使用 DHTML 控制項並將事件處理常式附加至它的 SelectedChanged 事件。請注意,即使控制項是位於表單標記 (Tag) 內,它也不是一個表單項目,同時也不會產生可以張貼至伺服器的名稱/值配對。

<%@Register TagPrefix="Custom" NameSpace="CustomControls" Assembly="CustomControls" %>
<script language="C#" runat = "server" >
private void SelectedChangedHandler(object sender, EventArgs e)
{
label.Text = "You selected the DHTML control";
}
</script>
<html>
 <body>  
    <form id="Form1" method="post" runat="server">
       <Custom:DHtmlControl OnSelectedChanged = "SelectedChangedHandler" runat="server" Text="SelectMe" />
       <br>
       <asp:Label id = "label" runat = "server" />
    </form> 
  </body>
</html>
[Visual Basic]
<%@Register TagPrefix="Custom" NameSpace="CustomControls" Assembly="CustomControls" %>
<script language="VB" runat = "server" >
    Private Sub SelectedChangedHandler(sender As Object, e As EventArgs)
       label.Text = "You selected the DHTML control"
    End Sub
</script>
<html>
 <body>  
    <form id="Form1" method="post" runat="server">
       <Custom:DHtmlControl OnSelectedChanged = "SelectedChangedHandler" runat="server" Text="SelectMe" />
       <br>
       <asp:Label id = "label" runat = "server" />
    </form> 
  </body>
</html>

請參閱

產生回傳的用戶端指令碼