WEBINAR:
On-Demand
Application Security Testing: An Integral Part of DevOps
The TextChanged Event
In the interest of space, I've included the finished version of the
LoadPostData method above, but I'll start by concentrating on the code relevant to the
TextChanged event first. The
postCollection argument that gets passed into this method contains all the posted information from the Web Form. In the second line of code above, I'm setting a string variable to the item in the collection identified by a certain identifier. Do you recognize that identifier? It should seem familiar to you. Back when you wrote the
Render method for the Web control, you set the
Name and
ID attributes on the tags that you rendered. If you recall, when you created the "input" tag that would render the textbox, the ID attribute was set to the control's
UniqueID property. The
s_PostedValue variable captures the text that the textbox contains at the moment of the postback. This is obtained from the NameValueCollection that the method received. Later below, that value is compared to the value of the
Text property. If the two values are not the same, then the text in the textbox has changed so you return a value of
true from the method. Returning a true value from this method will fire another method called
RaisePostDataChangedEvent. It is from this method that you'll raise the
TextChangedEvent.
The rest of the code in this method checks to see if you got here by an action caused by the textbox or the button. Since this method will get called if the button is pressed, you have to account for that and not just automatically call the "text changed" functionality. If you conclude that the button was the cause of the postback, you register that the control needs to call the RaisePostBackEvent and then continue through to the text change check. Below is the code for the RaisePostDataChangedEvent.
In VB.NET:
Public Sub RaisePostDataChangedEvent() Implements
IPostBackDataHandler.RaisePostDataChangedEvent
RaiseEvent TextChanged(Me, New EventArgs)
End Sub
In C#:
public void RaisePostDataChangedEvent()
{
if(this.TextChanged != null)
this.TextChanged(
this,new EventArgs());
}
As you can see, all you're doing here is raising the
TextChanged event. In order to properly integrate your control within the ASP.NET page lifecycle, you should raise the "data-change-oriented" events from this method instead of raising them directly from the
LoadPostData method. The code above takes care of checking for changes in posted data and setting up the task of raising events. What you still have left to do is somehow get this code to be called when the text is changed in the textbox. This is normally done through the
ontextchanged JavaScript event of a textbox, so you need to add another attribute to the "input" tag for the textbox. Since you want to give the choice of having the textbox cause a postback or not, much like the standard ASP.NET textbox, you need to add a Boolean property called
AutoPostBackEnabled. Once you've done that, you can use that property to set a condition around the attribute in addition to the textbox in the
Render method.
In VB.NET:
If Me.AutoPostBackEnabled Then
output.AddAttribute( _
HtmlTextWriterAttribute.Onchange, _
Page.GetPostBackEventReference( _
Me, "field"))
End If
output.RenderBeginTag(HtmlTextWriterTag.Input)
In C#:
if(this.AutoPostbackEnabled)
{
output.AddAttribute(
HtmlTextWriterAttribute.Onchange,
Page.GetPostBackEventReference(
this, "field")) ;
}
output.RenderBeginTag(HtmlTextWriterTag.Input);
You also need to inform the page that uses your control that you need to perform postbacks for data checking. To do this, the page uses its
RegisterRequiresPostBack method where it sends the class for the control. Fortunately, since you have access to the Page object from the Web control, you can perform the call there, thus encapsulating everything you need into the Web control. This eliminates the need to remember to make any calls about the control from every page that uses it. The call is made from your control's
OnPreRender event, which you must override.
In VB.NET:
Protected Overrides Sub OnPreRender(
ByVal e As EventArgs)
MyBase.OnPreRender(e)
If Not Page Is Nothing Then
Page.RegisterRequiresPostBack(Me)
End If
End Sub
In C#:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if(Page != null)
{
Page.RegisterRequiresPostBack(this);
}
}
Now you're ready to go. Your control can handle a server event upon clicking the button as well as a change of text in the textbox. The
AutoPostBackEnabled property allows the textbox to trigger the postback, though this is not the requirement for the
TextChanged event to be fired. Just like the standard ASP.NET textbox control, the
TextChanged event will be hit upon the next postback, even if it was not the textbox itself that triggered it. With a little creativity and possibly an extra property, you can code to customize this functionality to your liking.
The last thing you have to do with the Web control to give it maximum versatility is styling.