Web control library - position on web form

R

Robert Bull

I have created a web control library that contains a text box and a
search button that I plan on using multiple times. The functionality
of the control works fine. I can add the .dll to the toolbox and add
multiple instances of the control on the form, but the controls are
added as if the web form is in a flow layout. It only seems to be
happening with the custom contol because I can add buttons and they
render where I draw them. The following code is the html that creates
the custom control:

<cc2:ctlSearch id="CtlSearch1" style="Z-INDEX: 101; LEFT: 15px;
POSITION:absolute; TOP: 11px" runat="server"></cc2:ctlSearch></DIV>
<cc2:ctlSearch id="CtlSearch2" style="Z-INDEX: 101; LEFT: 104px;
POSITION: absolute; TOP: 421px" runat="server" Width="223px"
Height="22px"></cc2:ctlSearch>

The 'POSITION: absolute' should take care of this...shouldn't it? It
allows me to draw the control wherever I want in design mode but when
I view in the browser, it always renders at the top left corner of the
screen, stacked on top of each other. I override the render sub
routine in the web control library. Could this be the problem? I have
added the code to the web control library below. Thanks in advance

-Rob

Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Drawing
<DefaultProperty("Text"), ToolboxData("<{0}:ctlSearch
runat=server></{0}:ctlSearch>")> _
Public Class ctlSearch
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer

Dim _text As String
Protected WithEvents ddlSearchType As DropDownList
Protected WithEvents txtSearchCriteria As TextBox
Protected WithEvents lblSearchType As Label
Protected WithEvents lblSearchCriteria As Label
Protected WithEvents btnSearch As Button
<Bindable(True), Category("Appearance"), DefaultValue("")>
Property [Text]() As String
Get
Return _text
End Get

Set(ByVal Value As String)
_text = Value
End Set
End Property
Protected Overrides Sub Render(ByVal output As
System.Web.UI.HtmlTextWriter)
output.WriteFullBeginTag("Table")
output.WriteFullBeginTag("TR") 'Row 1 begin
output.WriteFullBeginTag("TD")
lblSearchType.RenderControl(output)
output.WriteEndTag("TD")
output.WriteFullBeginTag("TD")
ddlSearchType.RenderControl(output)
output.WriteEndTag("TD")
output.WriteFullBeginTag("TD")
txtSearchCriteria.RenderControl(output)
output.WriteEndTag("TD")
output.WriteFullBeginTag("TD")
btnSearch.RenderControl(output)
output.WriteEndTag("TD")

output.WriteEndTag("TR") 'Row 1 End
output.WriteEndTag("TABLE")
output.Flush()
End Sub
Protected Overrides Sub CreateChildControls()
'drop down list
ddlSearchType = New DropDownList
With ddlSearchType
.ID = "ddlSearchType"
.Width = Unit.Pixel(75)
.Items.Add("SSN")
.Items.Add("EMP#")
End With

'List Label
lblSearchType = New Label
With lblSearchType
.ID = "lblSearchType"
.Text = "Search Type: "
End With

'Criteria text box
txtSearchCriteria = New TextBox
With txtSearchCriteria
.ID = "txtSearchCriteria"
.Width = Unit.Pixel(150)
End With

'Criteria label
lblSearchCriteria = New Label
With lblSearchCriteria
.ID = "lblSearchCriteria"
End With

'Search Button
btnSearch = New Button
With btnSearch
.ID = "btnSearch"
.Text = "Search"
End With

'Add to the collection
Me.Controls.Add(lblSearchType)
Me.Controls.Add(ddlSearchType)
Me.Controls.Add(lblSearchCriteria)
Me.Controls.Add(txtSearchCriteria)
Me.Controls.Add(btnSearch)
End Sub
Public Sub New()
MyBase.New()
End Sub
Private Sub btnSearch_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnSearch.Click
'Me.txtSearchCriteria.Text = "Hello World"
End Sub
End Class
 
A

Alessandro Zifiglio

hi Robert, this is because you are overriding the render method of the
control. Move the code you have in your render method into the
createchildcontrols method and use a table control whereas to writing out
the raw table tags, since you are already overriding the createchildcontrols
method in the first place. Using a table control will also give you a much
cleaner and easier approach.

Another way to do it is to move the code you have in the render method to
the rendercontents method by overriding the RenderContents methods of the
WebControl class. This wont override the controls render method, instead you
are able to add your content(table) within the opening and closing tags of
your web control. In this manner you ensure that the functionality
implemented by your WebControl, such as style properties, height, width,
"the absolute position of your control" etc are not lost.

If you are overriding the render method to add a table as your outer most
tag since a span element is the default, then you can do this by calling the
new constructor in your webcontrol class like :
Public Sub New()
MyBase.New(HtmlTextWriterTag.Table)
End Sub

Now that you have added a table as the outermost tags, you just need to add
rows and cells in your rendercontents method. If your table needs to have
some extra attributes, then you can add them by additionally overriding the
AddAttributesToRender method :

Protected Overrides Sub AddAttributesToRender(writer As HtmlTextWriter)
writer.AddAttribute(HtmlTextWriterAttribute.Onclick,
"alert('Hello');")
writer.AddStyleAttribute(HtmlTextWriterStyle.Color, "Red")
'make sure you call the base webcontrol classes
AddAttributesToRender when your done as below
MyBase.AddAttributesToRender(writer)
End Sub

Regards,
Alessandro Zifiglio
http://www.dotnetbox.com

Robert Bull said:
I have created a web control library that contains a text box and a
search button that I plan on using multiple times. The functionality
of the control works fine. I can add the .dll to the toolbox and add
multiple instances of the control on the form, but the controls are
added as if the web form is in a flow layout. It only seems to be
happening with the custom contol because I can add buttons and they
render where I draw them. The following code is the html that creates
the custom control:

<cc2:ctlSearch id="CtlSearch1" style="Z-INDEX: 101; LEFT: 15px;
POSITION:absolute; TOP: 11px" runat="server"></cc2:ctlSearch></DIV>
<cc2:ctlSearch id="CtlSearch2" style="Z-INDEX: 101; LEFT: 104px;
POSITION: absolute; TOP: 421px" runat="server" Width="223px"
Height="22px"></cc2:ctlSearch>

The 'POSITION: absolute' should take care of this...shouldn't it? It
allows me to draw the control wherever I want in design mode but when
I view in the browser, it always renders at the top left corner of the
screen, stacked on top of each other. I override the render sub
routine in the web control library. Could this be the problem? I have
added the code to the web control library below. Thanks in advance

-Rob

Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Drawing
<DefaultProperty("Text"), ToolboxData("<{0}:ctlSearch
runat=server></{0}:ctlSearch>")> _
Public Class ctlSearch
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer

Dim _text As String
Protected WithEvents ddlSearchType As DropDownList
Protected WithEvents txtSearchCriteria As TextBox
Protected WithEvents lblSearchType As Label
Protected WithEvents lblSearchCriteria As Label
Protected WithEvents btnSearch As Button
<Bindable(True), Category("Appearance"), DefaultValue("")>
Property [Text]() As String
Get
Return _text
End Get

Set(ByVal Value As String)
_text = Value
End Set
End Property
Protected Overrides Sub Render(ByVal output As
System.Web.UI.HtmlTextWriter)
output.WriteFullBeginTag("Table")
output.WriteFullBeginTag("TR") 'Row 1 begin
output.WriteFullBeginTag("TD")
lblSearchType.RenderControl(output)
output.WriteEndTag("TD")
output.WriteFullBeginTag("TD")
ddlSearchType.RenderControl(output)
output.WriteEndTag("TD")
output.WriteFullBeginTag("TD")
txtSearchCriteria.RenderControl(output)
output.WriteEndTag("TD")
output.WriteFullBeginTag("TD")
btnSearch.RenderControl(output)
output.WriteEndTag("TD")

output.WriteEndTag("TR") 'Row 1 End
output.WriteEndTag("TABLE")
output.Flush()
End Sub
Protected Overrides Sub CreateChildControls()
'drop down list
ddlSearchType = New DropDownList
With ddlSearchType
.ID = "ddlSearchType"
.Width = Unit.Pixel(75)
.Items.Add("SSN")
.Items.Add("EMP#")
End With

'List Label
lblSearchType = New Label
With lblSearchType
.ID = "lblSearchType"
.Text = "Search Type: "
End With

'Criteria text box
txtSearchCriteria = New TextBox
With txtSearchCriteria
.ID = "txtSearchCriteria"
.Width = Unit.Pixel(150)
End With

'Criteria label
lblSearchCriteria = New Label
With lblSearchCriteria
.ID = "lblSearchCriteria"
End With

'Search Button
btnSearch = New Button
With btnSearch
.ID = "btnSearch"
.Text = "Search"
End With

'Add to the collection
Me.Controls.Add(lblSearchType)
Me.Controls.Add(ddlSearchType)
Me.Controls.Add(lblSearchCriteria)
Me.Controls.Add(txtSearchCriteria)
Me.Controls.Add(btnSearch)
End Sub
Public Sub New()
MyBase.New()
End Sub
Private Sub btnSearch_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnSearch.Click
'Me.txtSearchCriteria.Text = "Hello World"
End Sub
End Class
 

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,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top