Newbie: can't get custom control to hold contents when posting

K

kbutterly

Good afternoon all,

I have created a custom control which is a simple address control. The
control does not have a button in it; just the controls for the name
and address fields.

The control renders great when I add it to a web form, but when I
submit the form, I lose the data.

Now, I know that this has to do with post backs.

So, question #1: do I need to implement IPostBackDataHandler? If so,
then I know that I need to have LoadPostData and
RaisePostDataChangedEvent code. Unfortunately, I can't seem to find
any sample code for LoadPostData for a control with multiple controls
of different types, so I need some guidance in that area.

question #2: should I be using the Render or RenderContents method? I
am currently using RenderContents and I have lots of code like this:

output.AddAttribute("class", "row")
output.RenderBeginTag(HtmlTextWriterTag.Div) 'begin row div
output.AddAttribute("class", "firstCol")
output.RenderBeginTag(HtmlTextWriterTag.Div) 'begin firstcol div
output.RenderBeginTag(HtmlTextWriterTag.Label) 'begin label
output.Write("First")
output.RenderEndTag() 'end label
output.RenderEndTag() 'end firstcol
...etc...

However, I found an example in MSDN that just used the Render method. I
_think_ that I need the RenderContents method for the attributes???

Here is the bare outline of my custom control:

Namespace myCustomControls
<ToolboxData("<{0}:myAddressControl
runat=server></{0}:myAddressControl>")> _
Public Class myAddressControl
Inherits CompositeControl

Private txtFirstName As TextBox
Private txtLastName As TextBox
Private txtAddress1 As TextBox
Private txtAddress2 As TextBox
Private txtCity As TextBox
Private ddlState As DropDownList
Private txtZip As TextBox
Private _secondAddressLine As Boolean
Private arrStates() As String = {"Alabama", "Alaska", ..., "Wyoming"}



Property FirstName() As String
End Property

Property LastName() As String
End Property

Property Address1() As String
End Property

Property Address2() As String
End Property

Property City() As String
End Property

Property State() As String
End Property

Property Zip() As String
End Property

Public Property showSecondAddress() As Boolean
End Property


Protected Overrides Sub CreateChildControls()
End Sub

Protected Overrides Sub RenderContents(ByVal output As
HtmlTextWriter)
End Sub

Protected Overrides ReadOnly Property TagKey() As
System.Web.UI.HtmlTextWriterTag
End Property


End Class
End Namespace

I am hoping that I am just missing something very basic or just making
a stupid newbie error.

Any references, resources, or other assistance would be greatly
appreciated!

Thanks,
Kathryn
 
B

bruce barker

the default implementation of the webcontrol is to render a span with
the attributes set on the page. you then use rendercontents to output
the child controls. you can override the span by overriding TagKey. or
you can take complete control by putting everything in Render.


to get postback data you need to implement IPostbackDataHandler.
normally you'd name the control based on your controls uniqueid. then in
LoadPostBackData you can get their values

protected override bool LoadPostData(string key, NameValueCollection values)
{
_firstName = values[UniqueID + "_1"];
_lastName = values[UniqueID + "_2"];
}

-- bruce (sqlwork.com)
 
K

kbutterly

Bruce,

Thanks!

For archival purposes, here is the solution:

I was using CreateChildControls, but then in RenderContent, I was
recreating the controls.

I had code such as:

output.AddAttribute("class", "secondCol")
output.RenderBeginTag(HtmlTextWriterTag.Div) 'begin secondCol
output.AddAttribute("id", "txtAddress1")
output.AddAttribute("text", "")
output.RenderBeginTag(HtmlTextWriterTag.Input) 'begin input
output.RenderEndTag() 'end input
output.RenderEndTag() 'end secondCol

when what I needed was:

output.AddAttribute("class", "secondCol")
output.RenderBeginTag(HtmlTextWriterTag.Div) 'begin secondCol
txtAddress1.RenderControl(output)
output.RenderEndTag() 'end secondCol

Also, it turns out that I don't need the IPostBackDataHandler; the
CompositeControl seems to handle that.

Thanks again,
Kathryn

bruce said:
the default implementation of the webcontrol is to render a span with
the attributes set on the page. you then use rendercontents to output
the child controls. you can override the span by overriding TagKey. or
you can take complete control by putting everything in Render.


to get postback data you need to implement IPostbackDataHandler.
normally you'd name the control based on your controls uniqueid. then in
LoadPostBackData you can get their values

protected override bool LoadPostData(string key, NameValueCollection values)
{
_firstName = values[UniqueID + "_1"];
_lastName = values[UniqueID + "_2"];
}

-- bruce (sqlwork.com)

Good afternoon all,

I have created a custom control which is a simple address control. The
control does not have a button in it; just the controls for the name
and address fields.

The control renders great when I add it to a web form, but when I
submit the form, I lose the data.

Now, I know that this has to do with post backs.

So, question #1: do I need to implement IPostBackDataHandler? If so,
then I know that I need to have LoadPostData and
RaisePostDataChangedEvent code. Unfortunately, I can't seem to find
any sample code for LoadPostData for a control with multiple controls
of different types, so I need some guidance in that area.

question #2: should I be using the Render or RenderContents method? I
am currently using RenderContents and I have lots of code like this:

output.AddAttribute("class", "row")
output.RenderBeginTag(HtmlTextWriterTag.Div) 'begin row div
output.AddAttribute("class", "firstCol")
output.RenderBeginTag(HtmlTextWriterTag.Div) 'begin firstcol div
output.RenderBeginTag(HtmlTextWriterTag.Label) 'begin label
output.Write("First")
output.RenderEndTag() 'end label
output.RenderEndTag() 'end firstcol
...etc...

However, I found an example in MSDN that just used the Render method. I
_think_ that I need the RenderContents method for the attributes???

Here is the bare outline of my custom control:

Namespace myCustomControls
<ToolboxData("<{0}:myAddressControl
runat=server></{0}:myAddressControl>")> _
Public Class myAddressControl
Inherits CompositeControl

Private txtFirstName As TextBox
Private txtLastName As TextBox
Private txtAddress1 As TextBox
Private txtAddress2 As TextBox
Private txtCity As TextBox
Private ddlState As DropDownList
Private txtZip As TextBox
Private _secondAddressLine As Boolean
Private arrStates() As String = {"Alabama", "Alaska", ..., "Wyoming"}



Property FirstName() As String
End Property

Property LastName() As String
End Property

Property Address1() As String
End Property

Property Address2() As String
End Property

Property City() As String
End Property

Property State() As String
End Property

Property Zip() As String
End Property

Public Property showSecondAddress() As Boolean
End Property


Protected Overrides Sub CreateChildControls()
End Sub

Protected Overrides Sub RenderContents(ByVal output As
HtmlTextWriter)
End Sub

Protected Overrides ReadOnly Property TagKey() As
System.Web.UI.HtmlTextWriterTag
End Property


End Class
End Namespace

I am hoping that I am just missing something very basic or just making
a stupid newbie error.

Any references, resources, or other assistance would be greatly
appreciated!

Thanks,
Kathryn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top