"Error Creating Control" and "Cast from String"

L

Lisa

I'm creating a custom date control. In appearance, it's just a
textbox and a button. It has three custom properties: CalDate,
CalDateType and Required. Required is just a boolean, and CalDate is
the contents of the textbox. CalDateType is an enum with four values:
CalDate, Today, Jan_01_1900, and This_Year_Start. If it's CalDate, it
leaves CalDate alone; otherwise, it sets CalDate to the chosen value.

I'm having two problems. When I put the control into a test page, I
get a rectangle that says "Error Creating Control". When I mouse over
the block, it says "Cast from String". It doesn't say what I'm
improperly casting from a string, and the control compiles just fine.
The other problem, which is more minor, is that the control I drag
into the page is given the name LLCal2. I've never seen a control
that implements INamingContainer start with 2.

Here is the code:

Imports System
Imports System.IO
Imports System.ComponentModel
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls

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

Private DateBox As TextBox

Public Enum CalDateTypes
CalDate
Today
This_Year_Start
Jan_01_1900
End Enum

Public Sub New(ByVal sCalDateType As String, ByVal bRequired As
Boolean)
DateBox = New TextBox

ViewState("CalDateType") = sCalDateType
ViewState("Required") = bRequired

Select Case ViewState("CalDateType")
Case CalDateTypes.Jan_01_1900.ToString
DateBox.Text = "01/01/1900"
Case CalDateTypes.This_Year_Start.ToString
DateBox.Text = "01/01/" & CType(Year(Now), String)
Case CalDateTypes.Today.ToString
DateBox.Text = Now.ToString("MM/dd/yyyy")
End Select

End Sub

Public Sub New()
DateBox = New TextBox
ViewState("CalDateType") = CalDateTypes.CalDate.ToString
ViewState("Required") = False
End Sub

Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
MyBase.OnPreRender(e)
RegisterScript()
End Sub

Protected Overridable Sub RegisterScript()
If Not Page.IsClientScriptBlockRegistered("LLCal_vbs") Then
Dim reader As New
System.IO.StreamReader(Me.GetType().Assembly.GetManifestResourceStream(Me.GetType(),
"LLCal.vbs"))
Dim script As String = "<script language='vbscript'
type='text/vbscript' >" + ControlChars.Cr + ControlChars.Lf + "<!--" +
ControlChars.Cr + ControlChars.Lf + reader.ReadToEnd() +
ControlChars.Cr + ControlChars.Lf + "//-->" + ControlChars.Cr +
ControlChars.Lf + "</script>"
Page.RegisterClientScriptBlock("LLCal_vbs", script)
End If
End Sub

<Bindable(True), Browsable(True), Category("Appearance"),
DefaultValue(""), Description("The date which appears in the
textbox"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
_
Public Property CalDate() As String
Get
EnsureChildControls()
Return ViewState("CalDate")
End Get
Set(ByVal Value As String)
If Not IsDate(Value) Then
EnsureChildControls()
DateBox.Text = ""
ViewState("CalDate") = ""
Else
EnsureChildControls()
DateBox.Text = CType(Value,
Date).ToString("MM/dd/yyyy")
ViewState("CalDate") = CType(Value,
Date).ToString("MM/dd/yyyy")
End If
End Set
End Property

<Bindable(True), Browsable(True), Category("Appearance"),
DefaultValue(CalDateTypes.CalDate), Description("Default Value Type
for DateBox"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
_
Public Property CalDateType() As CalDateTypes
Get
Return ViewState("CalDateType")
End Get
Set(ByVal Value As CalDateTypes)
ViewState("CalDateType") = Value.ToString
Select Case Value
Case CalDateTypes.Jan_01_1900
DateBox.Text = "01/01/1900"
Case CalDateTypes.This_Year_Start
DateBox.Text = "01/01/" & CType(Year(Now), String)
Case CalDateTypes.Today
DateBox.Text = Now.ToString("MM/dd/yyyy")
End Select
End Set
End Property

<Bindable(True), Browsable(True), Category("Misc"),
DefaultValue(False), Description("Whether the datebox must have a
value or not"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
_
Public Property Required() As Boolean
Get
Return ViewState("Required")
End Get
Set(ByVal Value As Boolean)
ViewState("Required") = Value
End Set
End Property

Public Overrides ReadOnly Property Controls() As ControlCollection
Get
EnsureChildControls()
Return MyBase.Controls
End Get
End Property

Protected Overrides Sub CreateChildControls()

Controls.Clear()

Dim MyImage As System.Web.UI.WebControls.Image
Dim MyLabel As Label
Dim MyTable As Table
Dim MyRow As TableRow
Dim MyCell As TableCell

'<span style="font-size:6;background-color:silver;border:eek:utset
2" onclick="showCalHTML(document.myform.reportdate2, 4)"
name=choosereportdate2 id=choosereportdate2
onmousedown="this.style.borderStyle='inset'"
onmouseup="this.style.borderStyle='outset'"><img src="LLCal.gif"
border="0">&nbsp;</span>

' DateBox = New TextBox
DateBox.ID = "DateBox"
DateBox.Width = System.Web.UI.WebControls.Unit.Pixel(80)
DateBox.Attributes("RunAt") = "server"
DateBox.Attributes("OnBlur") = "me.value =
CorrectDate(me.value)"
DateBox.Attributes("OnFocus") = "me.select()"
DateBox.Text = ViewState("Value")
DateBox.EnableViewState = True

MyLabel = New Label
MyLabel.ID = "DateButton"
MyLabel.Attributes("style") = "font-size:6;
background-color:silver; border:eek:utset 2"
MyLabel.Attributes("onmouseup") =
"me.style.borderStyle='Outset'"
MyLabel.Attributes("onmousedown") =
"me.style.borderStyle='Inset'"
MyLabel.Attributes("onclick") = "showCal(" & Me.ClientID &
"_DateBox" & ")"
MyLabel.Attributes("align") = "absMiddle"

MyImage = New System.Web.UI.WebControls.Image

If Not System.IO.File.Exists("C:\temp\LLCal.gif") Then
Dim LLCal_gif() As System.Byte
Dim myAssembly As System.Reflection.Assembly =
System.Reflection.Assembly.GetExecutingAssembly
Dim myStream As Stream =
myAssembly.GetManifestResourceStream("LLCal.LLCal.gif")
LLCal_gif = New System.Byte(myStream.Length) {}
myStream.Read(LLCal_gif, 0, CInt(myStream.Length))
Dim myTempFile As New FileStream("C:\temp\LLCal.gif",
FileMode.Create)
myTempFile.Write(LLCal_gif, 0, CInt(myStream.Length))
myTempFile.Close()
End If

MyImage.ImageUrl = "C:\temp\LLCal.gif"
MyLabel.Controls.Add(MyImage)
MyLabel.Controls.Add(New LiteralControl("&nbsp;"))

MyTable = New Table
MyTable.BorderStyle = BorderStyle.None
MyTable.CellPadding = 0
MyTable.CellSpacing = 0

MyCell = New TableCell
MyCell.Attributes("style") = "padding:0"
MyCell.Controls.Add(DateBox)

MyRow = New TableRow
MyRow.Cells.Add(MyCell)

MyCell = New TableCell
MyCell.Attributes("style") = "padding:0"
MyCell.Controls.Add(MyLabel)

MyRow.Cells.Add(MyCell)

MyTable.Rows.Add(MyRow)

Controls.Add(MyTable)

End Sub

Protected Overrides Sub Render(ByVal output As
System.Web.UI.HtmlTextWriter)
Me.EnsureChildControls()
RenderContents(output)
End Sub

End Class

LLCal.gif, LLCal.bmp and LLCal.vbs are all in the assembly, so that I
can have the control be completely self-contained. Am I missing
something obvious here?

Thanks in advance,
Lisa
 
J

John Saunders

Lisa said:
I'm creating a custom date control. In appearance, it's just a
textbox and a button. It has three custom properties: CalDate,
CalDateType and Required. Required is just a boolean, and CalDate is
the contents of the textbox. CalDateType is an enum with four values:
CalDate, Today, Jan_01_1900, and This_Year_Start. If it's CalDate, it
leaves CalDate alone; otherwise, it sets CalDate to the chosen value.

I'm having two problems. When I put the control into a test page, I
get a rectangle that says "Error Creating Control". When I mouse over
the block, it says "Cast from String". It doesn't say what I'm
improperly casting from a string, and the control compiles just fine.

Lisa, I don't see any exception handling in the code you supplied, so it's
not surprising that there is no indication of where the "cast from string"
comes from.

What happens at runtime when you use this control on a page? Hopefully, the
"cast from string" exception will happen at runtime as well, and you'll be
able to see what's causing it.

The alternative requires a little work creating your own designer, so that
you can control what happens at design-time. I don't have an example handy,
but the basic idea is to derive your own designer from ControlDesigner (or
whatever the default designer is for the control your control derives from).
Then, override the GetDesignTimeHtml method like this:

namespace <yourControlsNamespace>.Design
{
public class MyControlsDesigner : ControlDesigner
{
protected override string GetDesignTimeHtml()
{
try
{
return base.GetDesignTimeHtml();
}
catch (Exception ex)
{
return CreatePlaceHolderDesignTimeHtml(ex.ToString());
}
}
}
}

Then specify this class as the designer for your control using the
DesignerAttribute:

[Designer(typeof(Design.MyControlsDesigner))]
public class MyControl : Control {}
 

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,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top