?
Solved

WebControl Property and rendered HTML attribute

Posted on 2009-04-21
9
Medium Priority
?
615 Views
Last Modified: 2012-06-27
Hello all,

Assume I have a custom WebControl with two properties: Text, and Other. If I render my control as a "<input type='text'" tag and render by properties as the following attributes on that tag, Text -> "value", Other -> "other" (see code below if that's confusing). So basically whatever is set as my control's Text property should be placed in the attribute called "value", and whatever is set as my control's Other property should be placed in the attribute called "other". How does my code (or .Net) know that I render a given property as this attribute, etc?

Does that question make sense? Is there a way to inform the compiler or framework (or something) that this property is rendered as this attribute name.
<Serializable()> _
Public Class TestControl
	Inherits WebControl
 
	Private _Text As String
	Private _Other As String
 
	Public Property Text() As String
		Get
			Return Me._Text
		End Get
		Set(ByVal value As String)
			_Text = value
		End Set
	End Property
	Public Property Other() As String
		Get
			Return _Other
		End Get
		Set(ByVal value As String)
			Me._Other = value
		End Set
	End Property
 
	Public Overrides Sub RenderBeginTag(ByVal writer As System.Web.UI.HtmlTextWriter)
		writer.WriteBeginTag("input")
	End Sub
	Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
		writer.WriteAttribute("id", Me.ClientID)
		writer.WriteAttribute("name", Me.ClientID)
		writer.WriteAttribute("value", Me.Text)
		writer.WriteAttribute("other", Me.Other)
		writer.WriteAttribute("onFocus", "this.select();")
	End Sub
	Public Overrides Sub RenderEndTag(ByVal writer As System.Web.UI.HtmlTextWriter)
		writer.Write(HtmlTextWriter.SelfClosingTagEnd)
	End Sub
 
End Class

Open in new window

0
Comment
Question by:tritonmgt
  • 5
  • 4
9 Comments
 
LVL 39

Expert Comment

by:abel
ID: 24194893
I think you are making it far too complex on yourself. On the Init event of your control, you can set the properties to the values you want. Just place this in the ASCX file:

<input type="text" runat="server" id="mytext" />

then you can do this:

mytext.value = Me.Text
mytext.setAttribute("other") = Me.Other

Note that the CLR does not know about your attributes, and it doesn't care either. You can output anything on the canvas that you like.
0
 
LVL 1

Author Comment

by:tritonmgt
ID: 24194934
So if the user types something into my rendered textbox the "value" attribute will change; how would my control update it's Text property based on that new information in the "value" attribute.
Know what I mean?
0
 
LVL 39

Expert Comment

by:abel
ID: 24195509
Yes, I know what you mean. There are several ways, and the easiest is the following (see code snip)

PS, Note that I think it is better to use ASPX controls instead of literals, it is easier to use:

<asp:TextBox runat="server" ID="mytext" />


<Serializable()> _
Public Class TestControl
        Inherits WebControl
 
 
       Public Property Text() As String
                Get
                        Return mytext.value
                End Get
                Set(ByVal value As String)
                        mytext.value= value
                End Set
        End Property
        Public Property Other() As String
                Get
                        Return mytext.getAttribute("other")
                End Get
                Set(ByVal value As String)
                         mytext.getAttribute("other") = value
                End Set
        End Property

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 1

Author Comment

by:tritonmgt
ID: 24196749
Ultimately, what I'm looking for is this:
Using my code structure included with the original question, I would declare the control on the page like so (see snippet, Part markup section). That control gets rendered like this (see snippet, Rendered HTML section).
How do I know that when the user changes the value in my text box that the "Text" property on my control should change? The same thing goes for the "Other" property.
I cannot get this part to work. Am I overlooking something ridiculously easy or just wording my problem incorrectly?

Page markup
----------------------------
<%@ Page Language="VB" %>
<%@ Register TagPrefix="TNet" Assembly="TNet.Web.UI.Controls.AutoCompleteControl" NameSpace="TNet.Web.UI.Controls"%>
 
<form runat="server">
    <TNet:TestControl ID="myControl" Runat="Server" Text="foo" Other="bar"/>
</form>
 
----------------------------
 
Rendered HTML
----------------------------
<form ...>
    <input type="text" id="myControl" name="myControl" value="foo" other="bar"/>
</form>
----------------------------

Open in new window

0
 
LVL 39

Accepted Solution

by:
abel earned 2000 total points
ID: 24198842
You can't know it the way you are programming it now. Please use the asp:TextBox controls, they have events that you can register to (just click the correct events in the dropdown of the control's code behind) and you should be fine.

If you must do it this way, prepare for a long road ....
0
 
LVL 1

Author Closing Comment

by:tritonmgt
ID: 31574734
Thanks for the direction abel. Just in case anyone should stumble across this question, my solution to the problem was such:

I inherited from the System.Web.UI.WebControls.TextBox class and added my own implementation of LoadPostData() method to parse the postCollection passed back from the page. I was able to retrieve the value for my control using this approach.
0
 
LVL 39

Expert Comment

by:abel
ID: 24238001
tritonmgt: I'll repeat your comment here, because EE doesn't show grading-comments, and it contained the solution:

I inherited from the System.Web.UI.WebControls.TextBox class and added my own implementation of LoadPostData() method to parse the postCollection passed back from the page. I was able to retrieve the value for my control using this approach.
On a side note: to achieve what you want, I didn't mean to inherit the textbox control (though there's nothing wrong in doing so) but I meant to just use the textbox value of the textbox you put on your usercontrol. Though, I must add, your solution is very pretty.

-- Abel --
0
 
LVL 1

Author Comment

by:tritonmgt
ID: 24238143
Abel:
I was not aware that EE did not show grading comments to the general user so I appreciate you doing that. And thank you for the compliment on the solution I used. It became quite bothersome for a few days.
I am including the relevant portions of the working code should anyone care to see exactly what I did to achieve the desired result.
A quick note: I wanted my custom control to render a textbox that, when it gained cursor focus, would display a custom list of items to suggest to the user. These items would work just like the items in a ComboBox (has a Text and Value property). The control would render an "<input type='text'/>" element along with an "<input type='hidden'/> element to the page - I set the ID of the hidden element to Me.ID & "_selectedValue". When the user selects an item from the list of suggestions, the javascript would set the textbox's value to the Text property of the item and would set the hidden's value to the Value property of the item (sorry if that's a bit confusing).
I chose this route because, as far as I could tell, you can only transmit a single value for a control during postback but I needed to send two values. To get around that limitation I ended up rendering two controls and setting/getting their values. So that is why you see me looking for two values in the LoadPostData() function.
If anyone has any questions or comments about the control or wants to see a live example, just let me know. I will be happy to assist in any way I can!

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
 
 
<DefaultProperty("Text"), ToolboxData("<{0}:AutoCompleteControl1 runat=server></{0}:AutoCompleteControl1>")> _
Public Class AutoCompleteControl
	Inherits TextBox
 
#Region "Privates"
	Private _Text As String
	Private _SelectedValue As String
#End Region
#Region "Properties"
	Public Shadows ReadOnly Property Text() As String
		Get
			If Me._Text IsNot Nothing Then
				Return Me._Text
			Else
				Return String.Empty
			End If
		End Get
	End Property
	Public Property SelectedValue() As String
		Get
			If Me._SelectedValue IsNot Nothing Then
				Return Me._SelectedValue
			Else
				Return String.Empty
			End If
		End Get
		Set(ByVal value As String)
			Me._SelectedValue = value
		End Set
	End Property
#End Region
#Region "Protected Methods"
	Protected Overrides Function LoadPostData(ByVal postDataKey As String, ByVal postCollection As System.Collections.Specialized.NameValueCollection) As Boolean
		Dim txt As String = postCollection(postDataKey)
		Dim selVal As String = postCollection(postDataKey & "_selectedValue")
		If txt IsNot Nothing Then
			Me._Text = txt
		End If
		If selVal IsNot Nothing Then
			Me._SelectedValue = selVal
		End If
	End Function
#End Region

Open in new window

0
 
LVL 39

Expert Comment

by:abel
ID: 24239562
Thanks for posting your full solution. There's nothing wrong with your approach, as far as I can see. And using the postCollection is a good method, anyway.
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In an ASP.NET application, I faced some technical problems. In this article, I list them out and show the solutions that I found.  I hope it will be useful. Problem: After closing a pop-up window, the parent page should be refreshed automaticall…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question