0

我有这段代码,它将 ax 数量的视图添加到 Multiview 控件。多视图控件存在于只有一个视图的页面上。在页面初始化上,我创建了 x 个视图,并在每个视图中添加了一个 GridView 控件,当我循环查找要显示哪个视图时,Multiview 控件说它只有 1 个视图。

    protected void variantRepeat_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        if (e.CommandSource.GetType() == typeof(LinkButton))
        {
            string theID = ((LinkButton)e.CommandSource).CommandArgument.ToString();
            ViewCollection views = prodView.Views; //this has only 1 view the one that has been added on the source view of the .aspx page
            foreach (View toDisplay in views)
            {
                if (toDisplay.ID == theID)
                    prodView.SetActiveView(toDisplay);
            }
        }

    }

上面的代码循环查找并显示视图。为什么所有视图都消失了,我已经逐步完成并在 init 完成处理数据库查询后,它有 x 个视图 > 源视图中的 1。

为什么这个控件会“失去”视图?

初始化代码:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.QueryString == null || Request.QueryString.Count < 1)
            Response.Redirect(Server.MapPath("~/Packages/"));
        if (!Page.IsPostBack)
        {
            if (Request.QueryString["id"].ToString() == string.Empty)
                Response.Redirect(Server.MapPath("~/Packages/"));
            var id = Server.HtmlEncode(Request.QueryString["id"].ToString());
            Guid packID = Guid.Parse(id);
            using (var context = new GaleEntities())
            {
                var thePackage = context.PackageEnts.First(p => p.packageID == packID);
                var theVariants = thePackage.Variants;
                var mydatasource = new List<PackageEnt> { thePackage };
                var myVariantDataSource = new List<Variant>();
                foreach (Variant single in theVariants)
                {
                    myVariantDataSource.Add(single);
                }
                packageForm.DataSource = mydatasource;
                variantRepeat.DataSource = myVariantDataSource;
                RenderProductGridviews(theVariants);
                prodView.SetActiveView(prodView.Views[0]);
            }
            packageForm.DataBind();
            variantRepeat.DataBind();
            Page.DataBind();
        }
    }

    protected void RenderProductGridviews(System.Data.Objects.DataClasses.EntityCollection<Variant> variantCol)
    {
        foreach (Variant packVar in variantCol)
        {

            View newView = new View();

            GridView prodGrid = new GridView();
            var myProdDataSource = new List<vw_VariantProduct>();             
            using (var context = new GaleEntities())
            {
                var singleProd1 = context.vw_VariantProduct.Where(vp => vp.variantID == packVar.variantID);
                foreach (vw_VariantProduct extProd in singleProd1)
                {
                    myProdDataSource.Add(extProd);
                }
            }
            prodGrid.DataSource = myProdDataSource;

            BoundField _column = new BoundField();
            _column.DataField = "product_title";
            _column.HeaderText = "Product";
            prodGrid.Columns.Add(_column);

            _column = new BoundField();
            _column.DataField = "product_title";
            _column.HeaderText = "Product";
            prodGrid.Columns.Add(_column);

            _column = new BoundField();
            _column.DataField = "product_desc";
            _column.HeaderText = "Description";
            prodGrid.Columns.Add(_column);

            _column = new BoundField();
            _column.DataField = "product_time";
            _column.HeaderText = "Time (mins)";
            prodGrid.Columns.Add(_column);

            _column = new BoundField();
            _column.DataField = "quantity";
            _column.HeaderText = "Quantity";
            prodGrid.Columns.Add(_column);

            prodGrid.DataBind();
            newView.ID = packVar.variantID.ToString();
            newView.Controls.Add(prodGrid);
            prodView.Views.Add(newView);
        }
    }
4

2 回答 2

3

现在,像往常一样,几乎所有与ASP.Net 中的动态控件有关的问题都有相同的常见问题......

您需要在每个帖子上创建动态控件,您只是在第一次加载页面时创建它们。遵循这个简单的规则:

  • 当您不使用母版页时,应在 PreInit 事件中创建动态控件,如果是,则在 Init 事件中创建控件
  • 避免在这些事件中设置可以在每个帖子中更改的属性,因为当应用视图状态时(在帖子事件中),这些属性将被覆盖
  • 每次发布页面时都必须创建动态控件,避免这种情况 if(!this.IsPostBack) this.CreatemyDynamicControls();
  • 当您在 PreInit 或 Init 事件中创建控件时,它们的状态将在 post 事件中自动设置,这意味着在 LoadComplete 事件中,您的控件将包含它们的状态,即使您在每个 post 中再次创建它们,即使您做了没有明确设置他们的状态。请注意,当您处理在设计时创建的控件时,此行为是不同的,在这种情况下,已设置状态的事件是 Load 事件
  • 事件订阅应该在 PageLoadComplete 之前发生,否则它们不会被引发

我已经发布了几个关于动态控件的答案:

https://stackoverflow.com/a/11127064/1268570

https://stackoverflow.com/a/11167765/1268570

按钮数组上的单击事件

点击事件后按钮数组消失

动态创建一个 ImageButton

这段代码按需创建动态控件,每个控件在每个帖子上保持其状态

public partial class DynamicControlsOnDemand : System.Web.UI.Page
{
    public int NumberOfControls
    {
        get
        {
            if (this.ViewState["d"] == null)
            {
                return 0;
            }
            return int.Parse(this.ViewState["d"].ToString());
        }
        set
        {
            this.ViewState["d"] = value;
        }
    }

    protected void Page_PreLoad(object sender, EventArgs e)
    {
        this.CreateDynamicControls();
    }

    protected void addControl_Click(object sender, EventArgs e)
    {
        this.NumberOfControls = this.NumberOfControls + 1;
        this.myPanel.Controls.Add(this.CreateTextbox(this.NumberOfControls));
    }

    private void CreateDynamicControls()
    {
        for (int i = 0; i < this.NumberOfControls; i++)
        {
            var t = this.CreateTextbox(i + 1);
            t.TextChanged += (x, y) => this.lblMessage.Text += "<br/>" + (x as TextBox).ID + " " + (x as TextBox).Text;

            this.myPanel.Controls.Add(t);
        }
    }

    private TextBox CreateTextbox(int index)
    {
        var t = new TextBox { ID = "myTextbox" + index.ToString(), Text = "de" };

        return t;
    }
}

ASPX

    <asp:Panel runat="server" ID="myPanel">
    </asp:Panel>
    <asp:Button Text="Add Control" runat="server" ID="addControl" OnClick="addControl_Click" />
    <asp:Label ID="lblMessage" runat="server" />

输出

在此处输入图像描述

于 2012-06-25T17:38:20.183 回答
1

您设置活动视图的第一个代码块是基于ItemCommand事件的,所以我假设这会在PostBack?

您在其中添加附加视图的代码Page_Load只有在没有回发时才会运行。尝试删除条件if(!Page.IsPostBack)语句。您需要在每个页面生命周期中添加动态控件。

于 2012-06-25T17:36:25.317 回答