Freigeben über


Beibehalten von clientseitigen Änderungen in anderen als Formularsteuerelementen

Clientseitiges ECMAScript (JScript, JavaScript) kann zum Verfolgen clientseitiger Statusänderungen in einem Steuerelement verwendet werden, sofern es sich dabei nicht um ein Formularelement handelt. Diese Steuerelemente verfügen nicht über Möglichkeiten zum Zurücksenden von Daten an den Server über eine Formularübermittlung. Das Ausführen eines Ereignis-Postbacks ist möglich, führt jedoch möglicherweise nicht zum gewünschten Erfolg. Das Problem kann durch die Verwendung einer ausgeblendeten Eingabedatei gelöst werden, die die Daten anstelle des Steuerelements überträgt. Das Steuerelement muss die ausgeblendeten Eingabefelder und das Skript, das die Statusinformationen an die ausgeblendeten Felder leitet, vor dem Einreichen des Formulars ausgeben. Sobald das Steuerelement geladen ist, können die Daten aus den ausgeblendeten Feldern vom Steuerelement abgerufen und verwendet werden. Zur Aktivierung dieses Mechanismus kann ein Steuerelement die RegisterHiddenField-Methode der eigenen Seite aufrufen, um ein ausgeblendetes Feld auszugeben und die IPostBackDataHandler-Schnittstelle zu implementieren, die den Wert des ausgeblendeten Feldes wiederherstellt und seine Eigenschaften aktualisiert.

Das folgende Beispiel demonstriert dieses Szenario. Das Steuerelement im Beispiel (DHtmlControl) gibt einen Abschnitt aus, dessen Farbe sich auf dem Client bei Auswahl ändert. Das Steuerelement gibt eine ausgeblendete Variable mit einem vom clientseitigen Skript auf eine boolesche Variable gesetzten Wert aus, die anzeigt, ob das Steuerelement ausgewählt wurde. Das Steuerelement legt eine boolesche Eigenschaft (Selected) offen, die angibt, ob das Steuerelement clientseitig ausgewählt wurde. Das Steuerelement implementiert die IPostBackDataHandler-Schnittstelle, so dass das Steuerelement den Wert des ausgeblendeten Feldes lesen und seine Selected-Eigenschaft aktualisieren kann, wenn die Seite an den Server gesendet wird. Das Steuerelement legt auch ein Ereignis (SelectedChanged) offen, das ausgelöst wird, wenn das Steuerelement auf dem Client ausgewählt wird.

Eine Anleitung zum Erstellen des Beispiels finden Sie unter Beispiele für Serversteuerelemente.

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

Seite mit DHTML-Steuerelement

Die folgende Seite verwendet ein DHTML-Steuerelement und fügt seinem SelectedChanged-Ereignis einen Ereignishandler hinzu. Beachten Sie, dass, obgleich sich das Steuerelement innerhalb von Formulartags befindet, es doch kein Formularelement ist und somit kein Name/Wert-Paar generiert, das an den Server gesendet werden kann.

<%@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>

Siehe auch

Generieren von clientseitigen Skripts für Postback