当前位置:  开发笔记 > 编程语言 > 正文

.NET中的动态控件问题

如何解决《.NET中的动态控件问题》经验,为你挑选了1个好方法。

动态控制问题

大家好,

我想创建一些动态控件,并让它们在页面加载中保持其viewstate.够容易吧?我所要做的就是在每次加载页面时使用相同的ID重新创建控件.但是,这是捕获 - 在我的PreRender事件中,我想要清除控件集合,然后使用新值重新创建动态控件.造成这种情况的原因很复杂,我可能需要大约一页来解释我为什么要这样做.所以,为了简洁起见,让我们假设我绝对必须这样做,而且别无他法.

在我的PreRender事件中重新创建控件后,问题出现了.重新创建的控件永远不会绑定到视图状态,并且它们的值不会跨页面加载持续存在.我不明白为什么会这样.我已经在我的OnLoad事件中重新创建了控件.当我这样做时,新创建的控件绑定到ViewState就好了,前提是我每次都使用相同的ID.但是,当我尝试在PreRender事件中执行相同的操作时,它会失败.

无论如何,这是我的示例代码:

namespace TestFramework.WebControls {

public class ValueLinkButton : LinkButton
{
    public string Value
    {
        get
        {
            return (string)ViewState[ID + "vlbValue"];
        }

        set
        {
            ViewState[ID + "vlbValue"] = value;
        }
    }
}

public class TestControl : WebControl
{
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        Controls.Clear();

        ValueLinkButton tempLink = null;

        tempLink = new ValueLinkButton();
        tempLink.ID = "valueLinkButton";
        tempLink.Click += new EventHandler(Value_Click);

        if (!Page.IsPostBack)
        {
            tempLink.Value = "old value";
        }

        Controls.Add(tempLink);
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        ValueLinkButton tempLink = ((ValueLinkButton)FindControl("valueLinkButton"));  //[CASE 1]

        //ValueLinkButton tempLink = new ValueLinkButton();  [CASE 2]

        tempLink.ID = "valueLinkButton";
        tempLink.Value = "new value";
        tempLink.Text = "Click";            

        Controls.Clear();
        Controls.Add(tempLink);
    }

    void Value_Click(object sender, EventArgs e)
    {
        Page.Response.Write("[" + ((ValueLinkButton)sender).Value + "]");
    }
}

}

因此,让我们检查案例1,其中[CASE 1]旁边的行没有被注释掉,但[CASE 2]旁边的行被注释掉了.一切都很好.当我将此控件放在页面上并加载页面时,我看到一个"Click"链接.当我点击链接时,页面输出文本"[新值]",在下一行,我们看到熟悉的"点击"链接.我点击"点击"链接的每个次要时间,我们都看到同样的事情.到现在为止还挺好.

但现在让我们来看一下案例2,其中[CASE 1]旁边的行被注释掉了,但[CASE 2]旁边的行没有被注释掉.在这里我们遇到了问题.加载页面时,我们会看到"点击"链接.但是,当我点击链接时,页面输出文本"[]"而不是"[新值]".click事件正常触发.但是,我分配给控件的Value属性的"新值"文本不会保持不变.再一次,这对我来说有点神秘.为什么当我在OnLoad中重新创建控件时,一切都很好,花花公子,但是当我在PreRender中重新创建控件时,值不会持续存在?

我觉得只需要有办法做到这一点.当我在PreRender中重新创建控件时,有没有办法将新创建的控件绑定到ViewState?

几天来我一直在努力.任何帮助,你可以给我我将不胜感激.

谢谢.



1> Joe..:

如果控件当前正在跟踪ViewState,则ViewState支持的属性仅保留到ViewState.这是为了使ViewState尽可能小:它应该只包含真正动态的数据.这样做的结果是:

在Init事件期间设置的ViewState propeties 不会备份到ViewState(因为Page尚未开始跟踪ViewState).因此,Init是添加控件和设置(a)不会在回发之间发生变化的属性(ID,CssClass ...)以及动态属性的初始值(可以通过其余部分中的代码修改)的好地方页面生命周期 - 加载,事件处理程序,PreRender).

在Load或PreRender中动态添加控件时,正在跟踪ViewState.然后,开发人员可以控制动态添加控件的持久性,如下所示:

在将控件添加到页面控件树之前设置的属性不会持久保存到ViewState.在将控件添加到控件树之前,通常会设置非动态属性(ID等).

将控件添加到页面控件树后设置的属性将持久保存到ViewState(从加载事件之前到PreRender事件之后启用ViewState跟踪).

在您的情况下,PreRender处理程序在将控件添加到页面的控制树之前设置属性.要获得所需的结果,请在将控件添加到控件树后设置动态属性:.

protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender(e);
    ValueLinkButton tempLink = new ValueLinkButton(); // [CASE 2]        
    tempLink.ID = "valueLinkButton"; // Not persisted to ViewState
    Controls.Clear();
    Controls.Add(tempLink);
    tempLink.Value = "new value";  // Persisted to ViewState
    tempLink.Text = "Click";       // Persisted to ViewState
}

推荐阅读
臭小子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有