0

我只是在玩自定义控件,并且构建了一个看起来像这样的控件:

<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();        
}

使用我拥有的代码,在第一次加载时一切都很好。我什至有一个与单击时触发的列表项相关的事件,并且有效。问题是自定义控件的更新没有发生。对于这个例子,我试图禁用用户最后单击的列表项,并确保所有其他项都已启用。这是控件的代码:

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);
        }


    }
}

我很确定它的 Rendering / CreateChildren 过程我做得不对。问题是我找不到一个很好的例子来说明如何在需要更新时重新呈现您的用户控件。有正确的方法吗?

4

1 回答 1

1

在我看来,您方法中的所有内容都Render()应该在您的CreateChildControls()方法中。

Render用于覆盖控件输出的实际 HTML。当响应流生成时,它将在生命周期的后期调用。

CreateChildControls可以在生命周期中的多个时间点调用,并且会在您的控件第一次需要被实例化时被调用——比如在 ViewState 处理期间。

于 2010-01-26T22:01:04.593 回答