Custom Control Not Rendering After Event
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?
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.
精彩评论