Loading UserControl using New Contructor

G

Guest

Hello All:

Do I have to use the LoadControl method of the Page to load a UserControl?

I have a class which contains three methods (one public and two private).
The class acts as a control server. It "serves" back the required control
(either WebControl or UserControl) based on the contents of an xml file. The
code in the webform places each control in a TableCell.

My problem is that the control server works as far as returning the correct
control; but when I view the webform, the UserControl is nowhere to be found.
It's not on the page and not in the View Source.

Here is the server code (I'm not posting GetWebControl here):

Public Function GetControl(ByVal NodeToRender As XmlNode) As
Web.UI.Control
Dim ValueToMatch As String
If NodeToRender.Name.Equals("DisplayText") Then
ValueToMatch = NodeToRender.Name.ToLower
Else
ValueToMatch = NodeToRender.Attributes("type").Value.ToLower
End If
Select Case ValueToMatch.ToLower
Case "label", "textbox", "checkbox", "displaytext"
Return GetWebControl(NodeToRender)

Case "customaddresses"
Return GetUserControl(NodeToRender)

End Select
End Function

Private Function GetUserControl(ByVal NodeToRender As XmlNode) As
Web.UI.UserControl
Dim uControl As New CustomAddresses

uControl.PopulateAddressBoxes(NodeToRender.Attributes("value").Value.Trim)
Return uControl
End Function

Here is the code and HTML for the UserControl (called CustomAddresses):

Public Class CustomAddresses
Inherits System.Web.UI.UserControl

Public Sub New()
Addr1 = New TextBox
Addr2 = New TextBox
Addr3 = New TextBox
Addr4 = New TextBox
End Sub

Public Sub PopulateAddressBoxes(ByVal str As String)
Dim SelectedValue() As String = str.Split(("/").ToCharArray())
Dim Name As String = SelectedValue(0).Trim
Dim Address() As String = SelectedValue(1).Split((",").ToCharArray())
Dim Addr1 As String = Address(0).Trim
Dim Addr2 As String = Address(1).Trim
Dim City As String = Address(Address.Length - 3).Trim
Dim StateProvCd As String = Address(Address.Length - 2).Trim
Dim PostalCode As String = Address(Address.Length - 1).Trim

Me.Addr1.Text = Name
Me.Addr2.Text = Addr1
If Not Addr2.Equals(City) Then
Me.Addr3.Text = Addr2
Me.Addr4.Text = City & " " & StateProvCd & ", " & PostalCode
Else
Me.Addr3.Text = City & " " & StateProvCd & ", " & PostalCode
End If
End Sub
End Class

<%@ Control Language="vb" AutoEventWireup="false"
Codebehind="CustomAddresses.ascx.vb" Inherits="WBMI.Claims.CustomAddresses"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<TABLE class="interior" id="Table1" width="100%">
<TR>
<TD class="tabledata">
<asp:TextBox id="Addr1" runat="server" Width="361px" ReadOnly="False"
MaxLength="60"></asp:TextBox></TD>
</TR>
<TR>
<TD class="tabledata">
<asp:TextBox id="Addr2" runat="server" Width="361px" ReadOnly="False"
MaxLength="60"></asp:TextBox></TD>
</TR>
<TR>
<TD class="tabledata">
<asp:TextBox id="Addr3" runat="server" Width="361px" ReadOnly="False"
MaxLength="60"></asp:TextBox></TD>
</TR>
<TR>
<TD class="tabledata">
<asp:TextBox id="Addr4" runat="server" Width="361px" ReadOnly="False"
MaxLength="60"></asp:TextBox></TD>
</TR>
</TABLE>

Here's a sample of the webform code that calls these:

If TypeOf SvrControl.GetControl(m_FormTemplate.GetControlNode(ChildNode)) Is
WebControl Then
ControlToRender =
CType(SvrControl.GetControl(m_FormTemplate.GetControlNode(ChildNode)),
WebControl)

ElseIf TypeOf
SvrControl.GetControl(m_FormTemplate.GetControlNode(ChildNode)) Is
UserControl Then
ControlToRender =
CType(SvrControl.GetControl(m_FormTemplate.GetControlNode(ChildNode)),
UserControl)

End If
NewCell.Controls.Add(ControlToRender)

What this boils down to is that I want to create and utilize a ControlServer
class to encapsulate the details about how a control is created and returned.

Can this be done?

TIA,
 
G

Guest

I figured out that I have to override the Render method in the UserControl.

I do not really understand the HtmlTextWriter. How do I write populated
TextBox controls to the webform?

Thank you for any available help.
 
P

Peter Rilling

Can you clarify more why you don't want to call LoadControl to load the
control. The reason LoadControl exists is so that ASP.NET has the ability
to prepare the object has it expects such as loading the ASCX and creating
an object model. If you create one with a constructor, then you prevent the
engine from doing what it was suppose to.

All controls have the Render method, but you should not override that in a
usercontrol. There are such things as custom web controls which inherit
from WebControl which you can then override the Render method.

All the HtmlTextWriter does is allow you to output the HTML. A textbox is
nothing more than <input type="text" value="something"/>.
 
G

Guest

Hi Peter,

We are using an xml document to "drive" the creation of web pages. The
document defines what controls to include on a webform and where where the
controls will appear.

I have alot of lead-way in defining how the document will be structured and
used.

My idea was to have a class to encapsulate the generation of the required
control (be it a WebControl or a UserControl) and returns it to the webform.
In this app, a UserControl is just a grouping of WebControls. For example,
one UserControl (CustomAddresses) is four textbox server controls grouped
together for name, address1, address2 and city-state-zip. This will be used
on the page when it will display a person's addresses.

Does this help you understand hat I am really trying to do?
 
M

Marina

I don't think this explains why you are against using LoadControl.

Joe said:
Hi Peter,

We are using an xml document to "drive" the creation of web pages. The
document defines what controls to include on a webform and where where the
controls will appear.

I have alot of lead-way in defining how the document will be structured
and
used.

My idea was to have a class to encapsulate the generation of the required
control (be it a WebControl or a UserControl) and returns it to the
webform.
In this app, a UserControl is just a grouping of WebControls. For
example,
one UserControl (CustomAddresses) is four textbox server controls grouped
together for name, address1, address2 and city-state-zip. This will be
used
on the page when it will display a person's addresses.

Does this help you understand hat I am really trying to do?
 
G

Guest

Hi Marina,

How would you use LoadControl from within the class that serves the
WebControls/UserControls? LoadControl must be called from a class that
inherits from the emplateControl class (i.e. Page and UserControl).

The whole point is to maximize flexibility by encapsulating the generation
of these controls, so that a webform (or another class) can simply request
the control that corresponds to an entry in the xml document.

If you know of another way to do this, please let me know. I would
appreciate any direction that you could provide.

Thanks,
 
M

Marina

If this is a usercontrol, nothing but another usercontrol or page can
possible do anything with it. It is a visual asp.net user control - windows
forms, etc. are not going to be able to do anything with it. Only the
ASP.NET engine can process it - which is why LoadControl was created, to do
just that. Because a constructor cannot do anything to help with rendering
it and instantiating it, and looking at the .ascx, etc etc.

So, even if you did manage to encapsulate it, only a page or usercontrol
would be able to use it anyway - so why bother?
 
G

Guest

Hi Marina,

Only a Page is going to use it.

The point is to encapsulate the process of creating it. To have one class
that accepts information (in this case, an XmlNode that has data that the
class uses to return the appropriate control) and returns a control - be it a
WebControl or a UserControl. I've encapsulated the process of returning
WebControls that are then placed in the appropriate places on the Page; now I
want to encapsulate the process of returning UserControls.

Why? Because we want a central unit to handle this functionality.

Any ideas?
 
M

Marina

That's fine. But why can't this unit use LoadControl? That is really the
question.

There are many way to accomplish this central place having access to
whatever page wants the user control created, so it can use the page's
LoadControl.

I think you are getting stuck in trying to box everything up, and not really
thinking about the functionality here. Only a Page can host a user control.
Only ASP.NET's engine can parse the .ascx, turn it into an object, use the
class behind it to render it all. So, whatever black box is going to have
this functionality, is going to need to have access to a Page on way or
another. It could be through inheritance, it could be through passing the
Page instance up, etc.
 
G

Guest

It can use LoadControl; in fact, I want to use LoadControl because I don't
want to bother overriding the Render method of the UserControl. The problem
is that I didn't have access to LoadControl from within my class (let's call
it ControlServer). So I instantiate and call ControlServer class from within
the Page (I am doing this now).

How would you pass a Page Instance up? Like so?

Dim sC as New ControlServer
sC.SomeMethod(Me, another_data_value)
 
M

Marina

Your thread started out saying you didn't want to use LoadControl, which is
why I was addressing that issue.

Yes, your code would look something like what you have there.
 
G

Guest

Hi Marina,

My thread started out with this:

Do I have to use the LoadControl method of the Page to load a UserControl?

I have a class which contains three methods (one public and two private).
The class acts as a control server. It "serves" back the required control
(either WebControl or UserControl) based on the contents of an xml file. The
code in the webform places each control in a TableCell.

**********************
Code and HTML snippets here
**********************

What this boils down to is that I want to create and utilize a ControlServer
class to encapsulate the details about how a control is created and returned.

Can this be done?



I don't see any mention of not wanting to use LoadControl. I asked if I had
to. And, now I know.

BTW, thanks for your help. This solves the problem. I appreicate it.
 
M

Marina

It came off that way, and from reading Peter's response, it seems to have
gotten that impression as well. Especially the subject where you ask about
using the New operator to do the instantiation.
 

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

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top