技术开发 频道

有关注册DataItem的一些可能被忽视的事情

    SwitchPartManager控件实现

    实现这么一个控件其实比想象中容易许多。处理这个问题的关键在于如何在(同步或异步)PostBack后正确地恢复当前已经加载的控件。只要能够正确恢复了控件的状态,剩下的问题都是由ASP.NET自身的机制来完成了,例如触发事件等等。

    我们来看一下SwitchPartManager的关键实现代码:

SwitchPartManager关键代码
[PersistChildren(false)]
[ParseChildren(true)]
[NonVisualControl]
public class SwitchPartManager : Control
{
private const string HiddenElementName = "__PartType__";
private bool initialized = false;
private string partTypeToSave = null;
public static SwitchPartManager GetCurrent(Page page)
{
return page.Items[typeof(SwitchPartManager)] as SwitchPartManager;
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (this.Page.Items.Contains(typeof(SwitchPartManager)))
{
throw new InvalidOperationException("One SwitchPartManager per page.");
}
this.Page.Items[typeof(SwitchPartManager)] = this;
this.Page.InitComplete += new EventHandler(Page_InitComplete);
this.Page.PreRenderComplete += new EventHandler(Page_PreRenderComplete);
}
private void Page_InitComplete(object sender, EventArgs e)
{
this.initialized = true;
string partType = this.Page.Request.Params[SwitchPartManager.HiddenElementName];
if (partType != null)
{
this.SwitchTo(partType);
}
}
private void Page_PreRenderComplete(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(this.partTypeToSave))
{
ScriptManager.RegisterHiddenField( this.Page, SwitchPartManager.HiddenElementName, this.partTypeToSave);
}
}
// 得到作为容器的UpdatePanel
private UpdatePanel PlaceHolderUpdatePanel
{
get
{
// ...
}
}
public void SwitchTo(string partType)
{
Control container = this.PlaceHolderUpdatePanel.ContentTemplateContainer;
container.Controls.Clear();
Control control = this.Page.LoadControl(partType + ".ascx");
control.ID = "JustToPreserveUniqueName";
container.Controls.Add(control);
this.partTypeToSave = partType;
}
}
    SwitchTo方法是用于切换用户控件的方法,它会将UpdatePanel内已有的控件(例如从ControlA切换到ControlB时,UpdatePanel中已经有了ControlA)清除,然后再向UpdatePanel中添加新的控件。

    我在这里将当前当前的控件标识记录在私有变量partTypeToSave中,它会在Page的PreRenderComplete时作为<input type="hidden" />的形式输出。我在这里使用了HiddenField作为保留控件选择状态的方式,这样可以避免因为ViewState被禁用而导致的数据丢失。

    这样,我们的页面在PostBack之后,就能够通过接受到的信息来恢复UpdatePanel的控件了。我在在Page的InitComplete时恢复UpdatePanel中的控件——很容易,直接使用SwitchTo方法就可以了。

    这几乎就是SwitchPartManager的完整代码。其实这个类相当的简单,但是它的价值却不小。但是根据我的经验,似乎为了自己的项目开发Custom Control的朋友不多,大家大都是在写用户控件(ascx)。其实在有些时候,为自己的应用编写一个Custom Control,尤其是用于“管理”的控件,其实能够使页面的逻辑变得清晰许多。
0
相关文章