ASP.NET动态控制数(创建控件,当您去) [英] ASP.NET dynamic controls count (creating controls as you go)

查看:172
本文介绍了ASP.NET动态控制数(创建控件,当您去)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个复合ASP.NET控件,它可以让你建立一个可编辑控件集合。

我的问题是,当我preSS添加或回发按钮(什么都不做比其他回发的形式),在文本框中输入的任何值都将丢失。

我不能让它当回发之间的变化控制数工作。我需要基本上能够在控制生命周期的两个不同的时间取决于视图国家财产 ControlCount 来重新创建控件树。

此测试可用于重现该问题:

 公共类AddManyControl:CompositeControl的
{
    保护覆盖无效的OnLoad(EventArgs的发送)
    {
        base.OnLoad(E);
        EnsureChildControls();
    }    保护覆盖无效的CreateChildControls()
    {
        变种数=的ViewState [ControlCount]为int? ?? 0;        的for(int i = 0; I<计数;我++)
        {
            VAR DIV =新HtmlGenericControl(分区);
            VAR的textBox =新的TextBox();
            textBox.ID =TB+我;
            div.Controls.Add(的textBox);
            Controls.Add被(DIV);
        }        的ViewState [ControlCount] =计数;        VAR btnAdd =新按钮();
        btnAdd.ID =添加;
        btnAdd.Text =添加文本框;
        btnAdd.Click + =新的EventHandler(btnAdd_Click);
        Controls.Add被(btnAdd);        VAR btnPostBack =新按钮();
        btnP​​ostBack.ID =回传;
        btnP​​ostBack.Text =做回发;
        Controls.Add被(btnPostBack);
    }    无效btnAdd_Click(对象发件人,EventArgs的发送)
    {
        的ViewState [ControlCount] =(INT)的ViewState [ControlCount] + 1;
    }    保护覆盖无效在preRender(EventArgs的发送)
    {
        base.On preRender(E);
        //如果我删除此RecreateChildControls通话
        //集合滞后每次回发的背后
        //因为伯爵在btnAdd_Click事件处理递增
        //但是,值不被丢失回发之间
        RecreateChildControls();
    }
}


解决方案

如果你想用ASP.NET的自定义控件玩,你AVE它的规则玩,和它的挑剔!当你开始用自定义控件在preRender玩,你知道你在错误的轨道上的90%的时间: - )

一般情况下,使用ViewState的最好的办法,就是要声明一个属性被它备份,就像标准的ASP.NET控件办(.net反射一直是我的老师几年了!)。这样一来,它会被读取和事件的生命周期期间自然保存

下面是一个code,似乎你想要做什么,很自然,没有任何技巧:

 公共类AddManyControl:CompositeControl的
{
    私人无效的AddControl(INT指数)
    {
        VAR DIV =新HtmlGenericControl(分区);
        VAR的textBox =新的TextBox();
        textBox.ID =TB+指数;
        div.Controls.Add(的textBox);
        Controls.AddAt(索引,DIV);
    }    保护覆盖无效的CreateChildControls()
    {
        的for(int i = 0; I< ControlsCount;我++)
        {
            的AddControl(ⅰ);
        }        VAR btnAdd =新按钮();
        btnAdd.ID =添加;
        btnAdd.Text =添加文本框;
        btnAdd.Click + =新的EventHandler(btnAdd_Click);
        Controls.Add被(btnAdd);        VAR btnPostBack =新按钮();
        btnP​​ostBack.ID =回传;
        btnP​​ostBack.Text =做回发;
        Controls.Add被(btnPostBack);
    }    私人诠释ControlsCount
    {
        得到
        {
            对象o =的ViewState [ControlCount];
            如果(O!= NULL)
                返回(INT)O;            返回0;
        }
        组
        {
            的ViewState [ControlCount] =值;
        }
    }    无效btnAdd_Click(对象发件人,EventArgs的发送)
    {
        诠释计数= ControlsCount;
        的AddControl(计数);
        ControlsCount =计数+ 1;
    }
}

I'm trying to create a composite ASP.NET control that let's you build an editable control collection.

My problem is that when I press the add or postback button (which does nothing other than to postback the form) any values entered in the text boxes are lost.

I can't get it to work when the number of controls change between postbacks. I need to basically be able to recreate the control tree at two different times in the control life-cycle depending on the view state property ControlCount.

This test can be used to reproduce the issue:

public class AddManyControl : CompositeControl
{
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        EnsureChildControls();
    }

    protected override void CreateChildControls()
    {
        var count = ViewState["ControlCount"] as int? ?? 0;

        for (int i = 0; i < count; i++)
        {
            var div = new HtmlGenericControl("div");
            var textBox = new TextBox();
            textBox.ID = "tb" + i;
            div.Controls.Add(textBox);
            Controls.Add(div);
        }

        ViewState["ControlCount"] = count;

        var btnAdd = new Button();
        btnAdd.ID = "Add";
        btnAdd.Text = "Add text box";
        btnAdd.Click += new EventHandler(btnAdd_Click);
        Controls.Add(btnAdd);

        var btnPostBack = new Button();
        btnPostBack.ID = "PostBack";
        btnPostBack.Text = "Do PostBack";
        Controls.Add(btnPostBack);
    }

    void btnAdd_Click(object sender, EventArgs e)
    {
        ViewState["ControlCount"] = (int)ViewState["ControlCount"] + 1;
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        // If I remove this RecreateChildControls call
        // the collection lags behind each postback
        // because the count is incremented in the btnAdd_Click event handler
        // however, the values are not lost between postbacks
        RecreateChildControls();
    }
}

解决方案

If you want to play with ASP.NET's custom controls, you ave to play by its rule, and its picky! When you start to play with the OnPreRender in a custom control, you know you're on the wrong track 90% of the time :-)

Generally, the best way to use the ViewState, is to declare a property backed up by it, just like the standard ASP.NET controls do (.NET Reflector has been my teacher for years!). This way, it will be read and saved naturally during the events lifecycle.

Here is a code that seems to do what you want, quite naturally, without any trick:

public class AddManyControl : CompositeControl
{
    private void AddControl(int index)
    {
        var div = new HtmlGenericControl("div");
        var textBox = new TextBox();
        textBox.ID = "tb" + index;
        div.Controls.Add(textBox);
        Controls.AddAt(index, div);
    }

    protected override void CreateChildControls()
    {
        for (int i = 0; i < ControlsCount; i++)
        {
            AddControl(i);
        }

        var btnAdd = new Button();
        btnAdd.ID = "Add";
        btnAdd.Text = "Add text box";
        btnAdd.Click += new EventHandler(btnAdd_Click);
        Controls.Add(btnAdd);

        var btnPostBack = new Button();
        btnPostBack.ID = "PostBack";
        btnPostBack.Text = "Do PostBack";
        Controls.Add(btnPostBack);
    }

    private int ControlsCount
    {
        get
        {
            object o = ViewState["ControlCount"];
            if (o != null)
                return (int)o;

            return 0;
        }
        set
        {
            ViewState["ControlCount"] = value;
        }
    }

    void btnAdd_Click(object sender, EventArgs e)
    {
        int count = ControlsCount;
        AddControl(count);
        ControlsCount = count + 1;
    }
}

这篇关于ASP.NET动态控制数(创建控件,当您去)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆