I built a composite control based on Chapter 5 of this book. When I try to associate the Label control with a field control I get the following error:
System.Web.HttpException: Unable to find control with id 'InputField' that is associated with the Label 'InputField_Label'.
I've tried literally everything I can think of to fix this, but have been unsuccessful. All the code to the relevant files is included below. Please help!
-Michael
P.S. My code is in
vb.net. A C# converter is available at
http://labs.developerfusion.co.uk/co...to-csharp.aspx
'================================================= ==============
' Default.aspx
'================================================= ==============
<%@ Page Language="
VB" AutoEventWireup="false" MasterPageFile="~/AdminTemplate.master" Theme="AdminDefault" Title="Virtual Food Court" CodeFile="Default.aspx.
vb" Inherits="CTT.VFC.UI.Pages._Default" %>
<%@ Register Namespace="CTT.VFC.UI.Components" TagPrefix="comp" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<table>
<comp:InputRow2 runat="server" ID="testrow" />
</table>
</asp:Content>
'================================================= ==============
' InputRow2.
vb
'================================================= ==============
Namespace CTT.VFC.UI.Components
Public Class InputRow2
Inherits CompositeControl
#Region "Child Control Declarations"
'Controls
Private ctrlField 'This is set as a textbox on default later, but it could be something else potentially
Private ctrlLabel As Label
'Containers
Private FieldContainer As InputRowContainer
Private LabelContainer As InputRowContainer
#End Region
#Region "Display Properties"
Private m_cssClassArray As Array = GetCssClasses(0)
Protected Property CssClasses() As Array
Get
Return m_cssClassArray
End Get
Set(ByVal value As Array)
m_cssClassArray = m_cssClassArray
End Set
End Property
Private m_labelCellWidth
Protected Property LabelCellWidth() As Integer
Get
Return m_labelCellWidth
End Get
Set(ByVal value As Integer)
m_labelCellWidth = value
End Set
End Property
Private m_fieldCellWidth
Protected Property FieldCellWidth() As Integer
Get
Return m_fieldCellWidth
End Get
Set(ByVal value As Integer)
m_fieldCellWidth = value
End Set
End Property
Protected Function GetCssClasses(ByVal intIndex As Integer) As Array
Dim aryReturn(6) As String
'Build Basic at Index:0
Select Case intIndex
Case 0
'MainContent
aryReturn(0) = "clsFormRowTable"
aryReturn(1) = "clsFieldLabelCell"
aryReturn(2) = "clsFieldLabelSubText"
aryReturn(3) = "clsInputFieldCell"
aryReturn(4) = "clsInputField"
aryReturn(5) = "clsFormBreakRow"
aryReturn(6) = "clsInputFieldHighlight"
Case 1
'Log-In
aryReturn(0) = "clsFormRowTableLogin"
aryReturn(1) = "clsFieldLabelCellLogin"
aryReturn(2) = "clsFieldLabelSubTextLogin"
aryReturn(3) = "clsInputFieldCellLogin"
aryReturn(4) = "clsInputFieldLogin"
aryReturn(5) = "clsFormBreakRowLogin"
aryReturn(6) = "clsInputFieldHighlightLogin"
End Select
Return aryReturn
End Function
#End Region
#Region "Properties"
Protected Overrides ReadOnly Property TagKey() As System.Web.UI.HtmlTextWriterTag
Get
Return HtmlTextWriterTag.Tr
End Get
End Property
#End Region
#Region "Subroutines & Functions"
Public Overrides ReadOnly Property Controls() As System.Web.UI.ControlCollection
Get
Me.EnsureChildControls()
Return MyBase.Controls
End Get
End Property
Protected Overrides Sub CreateChildControls()
Me.Controls.Clear()
FieldContainer = New InputRowContainer(InputRowContainerType.FieldDiv)
FieldContainer.ID = "FieldContainer"
CreateContainerChildControls(FieldContainer)
Me.AddContainer(FieldContainer)
LabelContainer = New InputRowContainer(InputRowContainerType.LabelDiv)
LabelContainer.ID = "LabelContainer"
CreateContainerChildControls(LabelContainer)
Me.AddContainer(LabelContainer)
'HOW DO I DO THIS???? -----------------------
ctrlLabel.AssociatedControlID = ctrlField.ID
'--------------------------------------------
ChildControlsCreated = True
End Sub
Protected Overridable Sub CreateContainerChildControls(ByVal container As InputRowContainer)
Select Case container.ContainerType
Case InputRowContainerType.FieldDiv
ctrlField = New TextBox
With ctrlField
.ID = "InputField"
.Text = ctrlField.ClientID '"Default Value"
.TextMode = TextBoxMode.SingleLine
.Rows = 1
.CssClass = CssClasses(4)
.Style.Add("display", "inline")
.Attributes.Add("OnFocus", "this.className='" & CssClasses(6) & "';")
.Attributes.Add("OnBlur", "this.className='" & CssClasses(4) & "';")
End With
container.Controls.Add(ctrlField)
Exit Select
Case InputRowContainerType.LabelDiv
ctrlLabel = New Label
With ctrlLabel
.ID = "InputField_Label"
'I commented it out here, cuz it doesn't work there either, and some of the stuff I found online told me to put it after both controls had been added.
'.AssociatedControlID = ctrlField.ID
.Text() = "Label Text"
.Style.Add("display", "inline")
End With
container.Controls.Add(ctrlLabel)
Exit Select
End Select
End Sub
Protected Overridable Sub AddContainer(ByVal container As InputRowContainer)
Controls.Add(container)
End Sub
Protected Overridable Function CreateContainer(ByVal containerType As InputRowContainerType) As InputRowContainer
Return New InputRowContainer(containerType)
End Function
Protected Overridable Sub RenderContainer(ByVal container As InputRowContainer, ByVal writer As HtmlTextWriter)
container.RenderControl(writer)
End Sub
Protected Overridable Sub RenderSpacerTableCell(ByVal width As Integer, ByVal writer As HtmlTextWriter)
writer.AddAttribute("width", width.ToString)
writer.RenderBeginTag(HtmlTextWriterTag.Td)
writer.Write("#160;")
writer.RenderEndTag()
End Sub
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
writer.AddAttribute("class", CssClasses(1))
writer.AddAttribute("width", Me.LabelCellWidth.ToString)
writer.RenderBeginTag(HtmlTextWriterTag.Td)
RenderContainer(LabelContainer, writer)
writer.RenderEndTag()
RenderSpacerTableCell(5, writer)
writer.AddAttribute("class", CssClasses(3))
writer.AddAttribute("width", Me.FieldCellWidth.ToString)
writer.RenderBeginTag(HtmlTextWriterTag.Td)
RenderContainer(FieldContainer, writer)
writer.RenderEndTag()
RenderSpacerTableCell(5, writer)
End Sub
#End Region
End Class
End Namespace
'================================================= ==============
' InputRowContainer.
vb
'================================================= ==============
Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports Microsoft.VisualBasic
Namespace CTT.VFC.UI.Components
''' <summary>
''' Summary description for CreditCardFormContainer
''' </summary>
Public Class InputRowContainer
Inherits Panel
Implements INamingContainer
Private m_containerType As InputRowContainerType
Public Sub New(ByVal containerType As InputRowContainerType)
Me.m_containerType = containerType
End Sub
Public ReadOnly Property ContainerType() As InputRowContainerType
Get
Return m_containerType
End Get
End Property
End Class
End Namespace
'================================================= ==============
' InputRowContainerType.
vb
'================================================= ==============
Imports Microsoft.VisualBasic
Namespace CTT.VFC.UI.Components
Public Enum InputRowContainerType
FieldDiv = 1
ValidationDiv = 2
LabelDiv = 3
SubLabelDiv = 4
End Enum
End Namespace
- Michael Levkoff -