2010-01-26 127 views
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); 
     } 


    } 
} 

我敢肯定它的渲染/ CreateChildren的过程,我不这样做的权利。问题是我找不到一个很好的例子,说明如何在需要更新时重新渲染你的用户控件。有没有正确的方法来做到这一点?

+0

刚刚检查了POST响应 - 无论出于何种原因标签被更新,但被禁用的按钮会恢复到原始状态。 – cschear 2010-01-26 22:14:10

回答

1

在我看来,你的Render()方法中的一切应该在你的CreateChildControls()方法中。

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

CreateChildControls可以在生命周期的几个点上调用,并且将在您的控件第一次需要实例化时调用 - 就像在ViewState处理期间一样。

+0

还是不行。点击事件触发(标签获取更新),但所选按钮不会被禁用。 – cschear 2010-01-26 22:10:31