locked
Control errors when looking for web resource RRS feed

  • Question

  • User-1226263862 posted

    I've got a custom server control that worked great until I populated the public properties from the front end and I'm looking for some direction.  Below is my code that works great to create a custom server control.

    namespace WebControls.ServerControls
    {
        /// <summary>
        /// General Textbox and calendar picker using AJAX
        /// </summary>
        [DefaultProperty("Text")]
        [ToolboxData("<{0}:CalendarPicker runat=server></{0}:CalendarPicker>")]
        public class CalendarPicker : WebControl, INamingContainer
        {
            protected TextBox txtDate;
            protected Image imgCal;
            protected CalendarExtender ce;
            protected CompareValidator cv;
            private ScriptManager sm;
            private string[] dateFormats = { "M/d/yy", "M/d/yyyy", "M/dd/yy", "M/dd/yyyy", "MM/d/yy", "MM/dd/yy", "MM/dd/yyyy", "M/d/yy" };
    
            /// <summary>
            /// Set/Gets the value of the textbox
            /// </summary>
            [Bindable(true)]
            [Category("Behavior")]
            [DefaultValue("")]
            [Localizable(false)]
            public string ValidationGroup
            {
                get
                {
                    EnsureChildControls();
                    return cv.ValidationGroup;
                }
    
                set
                {
                    EnsureChildControls();
                    cv.ValidationGroup = value;
                }
            }
    
            /// <summary>
            /// Set/Gets the value of the forecolor for the validation control.  Must use a name not a hex color.
            /// </summary>
            [Bindable(true)]
            [Category("Behavior")]
            [DefaultValue("")]
            [Localizable(false)]
            public System.Drawing.Color TextErrorColor
            {
                get
                {
                    EnsureChildControls();
                    return cv.ForeColor;
                }
    
                set
                {
                    EnsureChildControls();
                    cv.ForeColor = value;
                }
            }
    
            /// <summary>
            /// Set/Gets the value of the error message to display
            /// </summary>
            [Bindable(true)]
            [Category("Appearance")]
            [DefaultValue("")]
            [Localizable(false)]
            public string ErrorMessage
            {
                get
                {
                    EnsureChildControls();
                    return cv.ErrorMessage;
                }
    
                set
                {
                    EnsureChildControls();
                    cv.ErrorMessage = value;
                }
            }
    
            /// <summary>
            /// Selected date will return DateTime.Today if no date is selected
            /// </summary>
            [Bindable(true)]
            [Category("Appearance")]
            [DefaultValue("")]
            [Localizable(false)]
            DateTime _selectedDate;
            public DateTime? SelectedDate
            {
                get
                {
                    EnsureChildControls();
                    if (DateTime.TryParse(Convert.ToString(txtDate.Text.Trim()), out _selectedDate))
                    {
                        return _selectedDate;
                    }
                    else
                    {
                        return null;
                    }               
                }
                set
                {
                    EnsureChildControls();
                    if (value.HasValue)
                    {
                        txtDate.Text = value.Value.ToShortDateString();
                    }
                }
            }
    
            /// <summary>
            /// Override the CreateChildControls method to create the custom controls
            /// </summary>
            protected override void CreateChildControls()
            {
                txtDate = new TextBox();
                imgCal = new Image();
                ce = new CalendarExtender();
                cv = new CompareValidator();
    
                // textbox properties
                txtDate.ID = "DateText1";
                // add to page
                Controls.Add(txtDate);
                
                // image properties
                imgCal.ID = "CalendarImage1";
                imgCal.ToolTip = "Select a date";
                imgCal.ImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), @"WebControls.ServerControls.img.calendar.gif");
                // add to page
                Controls.Add(imgCal);
    
                // calendar extender properties
                ce.ID = "CalendarExtender1";
                ce.TargetControlID = txtDate.ID;
                ce.PopupButtonID = imgCal.ID;
                // add to page
                Controls.Add(ce);
    
                cv.ID = "CompareValidator1";
                cv.ControlToValidate = txtDate.ID;
                cv.Operator = ValidationCompareOperator.DataTypeCheck;
                cv.Type = ValidationDataType.Date;
                // add to page
                Controls.Add(cv);        
                
                base.CreateChildControls();
            }
    
            /// <summary>
            /// Render the controls on the page
            /// </summary>
            /// <param name="output"></param>
            protected override void Render(HtmlTextWriter output)
            {
                if (!this.DesignMode)
                {
                    // test for script manager
                    sm = ScriptManager.GetCurrent(Page);
                    if (sm == null)
                    {
                        throw new HttpException("A ScriptManager control must exist on the current page.");
                    }
                }
                txtDate.RenderControl(output);
                imgCal.RenderControl(output);
                ce.RenderControl(output);
                cv.RenderControl(output);
            }
        }
    }

    Below is my aspx page to test the control:

    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        start date: <cc1:CalendarPicker ID="CalendarPicker1" runat="server" TextErrorColor="Red" />
        <br />
        end date: <cc1:CalendarPicker ID="CalendarPicker2" runat="server" /> 
        <asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" TextErrorColor="Red" /> 
        <br />
        <asp:Label ID="lblMessage" runat="server" />
    </div>
    </form>

    When I remove the property values TextErrorColor, ValidationGroup and ErrorMessage it works great and will load the calendar image.  But when I assign a value to any one of those properties it bombs stating "Object reference not set to an instance of an object." 

    Any ideas on what I'm missing or have done incorrectly?

    Wednesday, October 5, 2011 5:06 PM

Answers

  • User-1226263862 posted

    After reading a bit more, it appears the Page object isn't always available in the CreateChildControls, so I moved it to the PreRender event like below and it works just fine.

    protected override void OnPreRender(EventArgs e)
            {
                imgCal.ImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "WebControls.ServerControls.img.calendar.gif");
                base.OnPreRender(e);
            }

     

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, October 6, 2011 8:37 AM