locked
ASP.NET servercontrol subcontrol as property default value set in properties doesn't render RRS feed

  • Question

  • User416664031 posted

    Hi,

    I created an asp.net server control see the following code:

     [ToolboxData("<{0}:CustomControl runat=server></{0}:CustomControl>")]
        [ToolboxBitmap(typeof(Calendar))]
        [ParseChildren(ChildrenAsProperties = true)]   
        public class CustomControl : CompositeControl
        {

            [Category("Appearance")]
            [Description("Sets the image inside the CustomControl")]
            [PersistenceMode(PersistenceMode.InnerDefaultProperty)]

          
            public ImageButton CalendarImageButton
            {

                get
                {
                    EnsureChildControls();               
                    return (ImageButton)ViewState["CalendarImageButton"];
                }

                set
                {
                    EnsureChildControls();
                    ViewState["CalendarImageButton"] = value;
                }
            }

           
            UpdatePanel updatePanel;

            protected override void RecreateChildControls()
            {
                EnsureChildControls();
            }

        

            protected override void CreateChildControls()
            {
                Controls.Clear();

                ViewState["CalendarImageButton"] = new ImageButton();

              
                updatePanel = new UpdatePanel();
                updatePanel.ID = "updatePanel";

              
                updatePanel.ContentTemplateContainer.Controls.Add((ImageButton)ViewState["CalendarImageButton"]);            

                this.Controls.Add(updatePanel);           
            }

    }

    This control contains an other (child)control as a public property that can be edited from Visual Studio's property window as a subproperty.

    Here follows my problem:

    <cc1:CustomControl ID="CustomControl1" runat="server">
    < CalendarImageButton ImageUrl="~/Images/add.png" />
    < /cc1:CustomControl>

    When I set the subcontrol's property (e.g. ImageUrl) at design-time the control renders well at design time in the editor. (I can see the set add.png)

    But when I start to run the code of the Website there is no picture set.

    When I set the CustomControl.CalendarImageButton.ImageUrl from c# code at the OnLoad event the control renders well, but if I only set the property from the Properties Window used at desing time the image is missing.

    What am I missing from my code?

    Your help would be appreciated.

    Thank you in advance!

    Attila Fur

    Wednesday, November 20, 2013 7:22 AM

Answers

  • User-933407369 posted

    hi fur.attila,

    Your CustomControls is not correct, you can try the following code:

    using System.Web.UI;
    
    using System;
    
    using System.Collections.Generic;
    
    using System.ComponentModel;
    
    using System.Linq;
    
    using System.Text;
    
    using System.Web;
    
    using System.Web.UI.WebControls;
    
    using System.Drawing;
    
    using System.IO;
    
    using System.Web.UI.HtmlControls;
    
    namespace CustomControls
    {
    
        [ToolboxData("<{0}:CustomControl runat=server></{0}:CustomControl>")]
    
        [ToolboxBitmap(typeof(Calendar))]
    
        [ParseChildren(ChildrenAsProperties = true)]
    
        public class CustomControl : CompositeControl
        {
    
            [Category("Appearance")]
    
            [Description("Sets the image for the calendar control")]
    
            [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
    
            public ImageButton CalendarImageButton
            {
    
                get
                {
    
                    EnsureChildControls();
    
                    return (ImageButton)ViewState["CalendarImageButton"];
    
                }
    
                set
                {              
                   ViewState["CalendarImageButton"] = value; EnsureChildControls();             }
    
            }
    
            UpdatePanel updatePanel;
    
            protected override void RecreateChildControls()
            {
    
                EnsureChildControls();
    
            }
    
    
    
            protected override void CreateChildControls()
            {
    
                Controls.Clear();
    
               //ViewState["CalendarImageButton"] = new ImageButton(); 
                updatePanel = new UpdatePanel();
    
                updatePanel.ID = "updatePanel";
    
                updatePanel.ContentTemplateContainer.Controls.Add((ImageButton)ViewState["CalendarImageButton"]);
    
                this.Controls.Add(updatePanel);
    
            }
    
        }
    
    }

    It is  working well for you.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, November 28, 2013 9:36 PM
  • User416664031 posted

    I tried your suggestion, but it didn't solve my problem.

    Finally I figured out that the OnInit eventhandler should be overridden by this:

    protected override void OnInit(EventArgs e)

    {

    base.OnInit(e);

    ViewState["CalendarImageButton"] = new ImageButton();

    }

    Thank you both for the help!

    Attila

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 4, 2013 7:15 AM

All replies

  • User-933407369 posted

    hi fur.attila ,

     it seems that it’s a ToolboxBitmap issue, you can search the related information on the forums:

     http://social.msdn.microsoft.com/Forums/en-US/home?searchTerm=ToolboxBitmap+

    I would suggest you read the reference below:

    How to: Provide a Toolbox Bitmap for a Control

    http://msdn.microsoft.com/en-us/library/4wk1wc0a(v=vs.90).aspx

    you also can Refer to the links :

    How to: Create a Date Picker Composite Control in ASP.NET (C#)

    http://www.codeproject.com/Articles/37814/How-to-Create-a-Date-Picker-Composite-Control-in-A

    Hope it helps you.

    Thursday, November 21, 2013 12:56 AM
  • User416664031 posted

    Hi Happy Chen,

    Thank you for the answer, but propably I didn't declare my issue correctly. It is not a ToolboxBitmap issue. I have an ImageButton inside my servercontrol that doesn't render on PageLoad when I set the ImageUrl from the Visual Studio's property window (see the initial aspx given above). The Image renders only if I set it programatically from the OnLoad event (I definitely don't want to do this.)

    It seems that somehow the set property(ImageUrl) is lost on PageRender, or not passed into the servercontrol itself to render it in the CreateChildControls event.

    During designtime the CreateChildControls works perfectly the Image is shown inside the servercontrol.

    How can this be? Please help it is driving me crazy

     

    Thursday, November 21, 2013 4:01 AM
  • User416664031 posted

    I still couldn't find any solution. I decided to take some screenshots to highlight the problem better..

    During desingtime seems everything ok:

    http://mcleod.hu/pics/1.png

    The control inside the aspx page looks like this (after setting the ImageUrl property):

    <cc1:CustomControl ID="CustomControl1" runat="server">

    <CalendarImageButton ImageUrl="~/Images/add.png" />

    </cc1:CustomControl>


    Here comes the bug:

    http://mcleod.hu/pics/2.png

    Is it and ASP.NET Issue, or am I using something in a wrong way?

    Any help would be appreciated.

    Attila Fur

    Friday, November 22, 2013 3:10 PM
  • User-933407369 posted

    Can you post the complete  markup or provide a simple demo, which can easily reproduce the problem? you can upload the sample to skydrive

    Because i don't know that  what is the CustomControl doing.

    In order to help us to understand your issue better.

    Thanks.

    Wednesday, November 27, 2013 5:03 AM
  • User416664031 posted

    CustomControl is not doing anything rigth now, it is only for test purpose.

    Here is my testpage (complete markup):

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="WebForm1.aspx.cs" Inherits="Default2" %>

    <%@ Register assembly="CustomControls" namespace="CustomControls" tagprefix="cc1" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml">

    <head runat="server">

    <title></title>

    </head>

    <body>

    <form id="form1" runat="server">

    <div>

    <asp:ScriptManager ID="ScriptManager1" runat="server">

    </asp:ScriptManager>

    <cc1:CustomControl ID="CustomControl1" runat="server">

    <CalendarImageButton ImageUrl="~/Images/add.png" />

    </cc1:CustomControl>

    <br />

    </div>

    </form>

    </body>

    </html>



    Here is the code for the so called "CustomControl":


    using System.Web.UI;

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Linq;

    using System.Text;

    using System.Web;

    using System.Web.UI.WebControls;

    using System.Drawing;

    using System.IO;

    using System.Web.UI.HtmlControls;

    namespace CustomControls

    {

    [ToolboxData("<{0}:CustomControl runat=server></{0}:CustomControl>")]

    [ToolboxBitmap(typeof(Calendar))]

    [ParseChildren(ChildrenAsProperties = true)]

    public class CustomControl : CompositeControl

    {

    [Category("Appearance")]

    [Description("Sets the image for the calendar control")]

    [PersistenceMode(PersistenceMode.InnerDefaultProperty)]

    public ImageButton CalendarImageButton

    {

    get

    {

    EnsureChildControls();

    return (ImageButton)ViewState["CalendarImageButton"];

    }

    set

    {

    EnsureChildControls();

    ViewState["CalendarImageButton"] = value;

    }

    }

    UpdatePanel updatePanel;

    protected override void RecreateChildControls()

    {

    EnsureChildControls();

    }

     

    protected override void CreateChildControls()

    {

    Controls.Clear();

    ViewState["CalendarImageButton"] = new ImageButton();

    updatePanel = new UpdatePanel();

    updatePanel.ID = "updatePanel";

    updatePanel.ContentTemplateContainer.Controls.Add((ImageButton)ViewState["CalendarImageButton"]);

    this.Controls.Add(updatePanel);

    }

    }

    }

    This control is not doing anything, I just want to get rendered the CalendarImageButton's Image on PageLoad event from in the markup data.

    Thanks for trying to help!

    Thursday, November 28, 2013 5:15 PM
  • User-933407369 posted

    hi fur.attila,

    Your CustomControls is not correct, you can try the following code:

    using System.Web.UI;
    
    using System;
    
    using System.Collections.Generic;
    
    using System.ComponentModel;
    
    using System.Linq;
    
    using System.Text;
    
    using System.Web;
    
    using System.Web.UI.WebControls;
    
    using System.Drawing;
    
    using System.IO;
    
    using System.Web.UI.HtmlControls;
    
    namespace CustomControls
    {
    
        [ToolboxData("<{0}:CustomControl runat=server></{0}:CustomControl>")]
    
        [ToolboxBitmap(typeof(Calendar))]
    
        [ParseChildren(ChildrenAsProperties = true)]
    
        public class CustomControl : CompositeControl
        {
    
            [Category("Appearance")]
    
            [Description("Sets the image for the calendar control")]
    
            [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
    
            public ImageButton CalendarImageButton
            {
    
                get
                {
    
                    EnsureChildControls();
    
                    return (ImageButton)ViewState["CalendarImageButton"];
    
                }
    
                set
                {              
                   ViewState["CalendarImageButton"] = value; EnsureChildControls();             }
    
            }
    
            UpdatePanel updatePanel;
    
            protected override void RecreateChildControls()
            {
    
                EnsureChildControls();
    
            }
    
    
    
            protected override void CreateChildControls()
            {
    
                Controls.Clear();
    
               //ViewState["CalendarImageButton"] = new ImageButton(); 
                updatePanel = new UpdatePanel();
    
                updatePanel.ID = "updatePanel";
    
                updatePanel.ContentTemplateContainer.Controls.Add((ImageButton)ViewState["CalendarImageButton"]);
    
                this.Controls.Add(updatePanel);
    
            }
    
        }
    
    }

    It is  working well for you.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, November 28, 2013 9:36 PM
  • User416664031 posted

    Hi Happ Chen,

    The code isn't working for me. The error is :

    An unhadled exception has occured.

    Value cannot be null.
    Parameter name: child

    see the following link: http://mcleod.hu/pics/3.png

    Probably the removal of //ViewState["CalendarImageButton"] = new ImageButton(); caused this. There is no object created in the CreateChildControls method of the CustomControl. (When I uncomment this part, the control renders, but shows the same error, detailed above)

    Friday, November 29, 2013 8:24 AM
  • User-227760790 posted

    hi fur.attila,

    Have you rebuild your CustomControl .dll file ?

    You need to rebuild your project and add  .dll  refernce which is CustomControl classlibary.

    Sunday, December 1, 2013 9:09 PM
  • User416664031 posted

    Hi Galeny,

    Yes I do always rebuild my CustomControl, and delete dll-s and references in my test project

    But thanks anyway.

    Tuesday, December 3, 2013 4:46 AM
  • User-227760790 posted

    is it working for you ?

    Tuesday, December 3, 2013 4:48 AM
  • User416664031 posted

    No.

    Tuesday, December 3, 2013 4:50 AM
  • User-227760790 posted

    I don't know that what happens in your project.

    I try it out , and it is working for me  as happy said .

    Can you post the complete  markup or provide a simple demo, easily reproduce your issue?

    Tuesday, December 3, 2013 4:55 AM
  • User416664031 posted

    I think I will create a whole new project for the test and for the customcontrol itself....

    Tuesday, December 3, 2013 5:02 AM
  • User416664031 posted

    OK guys! You are right it works, but only in the case if the control's markup is like this:

    <cc1:CustomControl ID="CustomControl1" runat="server">

    <CalendarImageButton ImageUrl="~/Images/add.png" />

    </cc1:CustomControl>

    If you drag the control from the Toolbox it will render like this (Without the CalendarImageButton part.):

    <cc1:CustomControl ID="CustomControl1" runat="server">

    </cc1:CustomControl>


    And of course comes the null exception detailed above, and I cannot change/or select properties in the Properties Window during runtime, because the subcontrol shows this error: Value cannot be null.
    Parameter name: child

    How can this be avoided? I would like to drag my control from the Toolbox, and edit afterwards in the Properties Window.

    Thank you for your help

    Tuesday, December 3, 2013 7:39 AM
  • User-227760790 posted

    you can try to override EnsureChildControls

      protected override void EnsureChildControls()
            {
                Controls.Clear();
    
                //ViewState["CalendarImageButton"] = new ImageButton();
    
                updatePanel = new UpdatePanel();
                ImageButton image = new ImageButton();
                image.ID = "image"; 
                image.ImageUrl = "";
                updatePanel.ID = "updatePanel";
    
                updatePanel.ContentTemplateContainer.Controls.Add(image);
    
                this.Controls.Add(updatePanel);
            }

    Wednesday, December 4, 2013 12:39 AM
  • User416664031 posted

    I tried your suggestion, but it didn't solve my problem.

    Finally I figured out that the OnInit eventhandler should be overridden by this:

    protected override void OnInit(EventArgs e)

    {

    base.OnInit(e);

    ViewState["CalendarImageButton"] = new ImageButton();

    }

    Thank you both for the help!

    Attila

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 4, 2013 7:15 AM