views:

161

answers:

1

I am just playing with custom controls, and have one built that looks like so:

<cc:Test ID="jqTestTest01" runat="server" OnTestClick="jqTestTest01_TestClick">
    <TestItems>
            <asp:ListItem Text="Tab One" Value="1" Selected="True" />
            <asp:ListItem Text="Tab Two" Value="2" />
            <asp:ListItem Text="Tab Three" Value="3" />
            <asp:ListItem Text="Tab Four" Value="4" />
            <asp:ListItem Text="Tab Five" Value="5" />
    </TestItems>
    <ContentTemplate>
            <asp:Label ID="lblTestTest01" runat="server" Text="None" />            
    </ContentTemplate>    
</cc:Test>

protected void jqTestTest01_TestClick(object sender, EventArgs e)
{
    lblTestTest01.Text = "Click Event! " + DateTime.Now.ToLongTimeString();        
}

With the code that I have everything is rendering fine on the first load. I even have a event tied to the list items that fires when clicked, and that works. The problem is updates to the custom control are not taking place. For this example I am trying to disable the listitem the user last clicked, and make sure all others are enabled. Here is the code for the control:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;

namespace MyControls.jqTest
{
    [ParseChildren(true), PersistChildren(false)]
    public class Test : WebControl, INamingContainer
    {
        [ParseChildren(true, "Items")]
        public class iTestItems
        {
            private ListItemCollection _Items;

            [DefaultValue((string)null), MergableProperty(false), PersistenceMode(PersistenceMode.InnerDefaultProperty)]
            public virtual ListItemCollection Items
            {
                get
                {
                    if (_Items == null)
                        _Items = new ListItemCollection();

                    return _Items;
                }
            }
        }

        private iTestItems _TestItems = null;
        private ITemplate _ContentTemplate = null;
        public event EventHandler TestClick = null;

        [PersistenceMode(PersistenceMode.InnerProperty),
         TemplateContainer(typeof(iTestItems)),
         TemplateInstance(TemplateInstance.Single)]
        public iTestItems TestItems
        {
            get { return _TestItems; }
            set { _TestItems = value; }
        }

        [PersistenceMode(PersistenceMode.InnerProperty),
         TemplateContainer(typeof(TemplateControl)),
         TemplateInstance(TemplateInstance.Single)]
        public ITemplate ContentTemplate
        {
            get { return _ContentTemplate; }
            set { _ContentTemplate = value; }
        }

        protected override void CreateChildControls()
        {
            Controls.Clear();
            Control BtnList = new Control();            
            Controls.Add(BtnList);

            Control Content = new Control();
            ContentTemplate.InstantiateIn(Content);
            Controls.Add(Content);
        }

        void Btn_Click(object sender, EventArgs e)
        {
            Button Btn = (Button)sender;
            foreach (ListItem i in _TestItems.Items)
                i.Selected = (i.Text == Btn.Text) ? false : true;

            if (TestClick != null)
                TestClick(sender, e);
        }

        protected override void Render(HtmlTextWriter writer)
        {

            Control BtnList = Controls[0];
            BtnList.Controls.Clear();

            foreach (ListItem i in _TestItems.Items)
            {
                Button Btn = new Button();
                Btn.Text = i.Text;
                Btn.Enabled = i.Selected ? false : true;
                Btn.Click += new EventHandler(Btn_Click);
                BtnList.Controls.Add(Btn);
            }

            base.Render(writer);
        }


    }
}

I'm pretty sure its the Rendering / CreateChildren process that I'm not doing right. Problem is I cant find a good example that shows how to rerender your usercontrol when something needs updating. Is there a right way to do this?

+1  A: 

It seems to me that everything inside of your Render() method should be inside your CreateChildControls() method.

Render is for overriding the actual HTML that is output by your control. It will be called later in the lifecycle when the response stream is being generated.

CreateChildControls can be called at several points in the lifecycle, and will be called the first time your control needs to be instantiated - like during ViewState handling.

womp
Still no go. The click event is firing off (the label gets updated), but the selected button does not get disabled.
Chris