1

我正在向更新面板动态添加自定义用户控件。我的用户控件包含两个下拉列表和一个文本框。当更新面板之外的控件触发回发时,我将用户控件重新添加到更新面板。

问题是......当我重新添加用户控件时,在回发时,它会触发用户控件内下拉列表的“SelectedIndexChanged”事件。即使 selectedindex 自上次回发以来没有更改。

有任何想法吗?

如有必要,我可以发布代码,但在这种特殊情况下有很多。

提前致谢!

编辑...下面添加的代码

* .ASCX

<asp:DropDownList ID="ddlColumns" OnSelectedIndexChanged="ddlColumns_SelectedChanged" AppendDataBoundItems="true" AutoPostBack="true" runat="server">

* .ASCX.CS

List<dataColumnSpecs> dataColumns = new List<dataColumnSpecs>();

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        fillDDLColumns();
    }        
}

public void fillDataColumnsList()
{
    dataColumns.Clear();
    //COMMON GETDATATABLE RETURNS A DATA TABLE POPULATED WITH THE RESULTS FROM THE STORED PROC COMMAND
    DataTable dt = common.getDataTable(storedProcs.SELECT_COLUMNS, new List<SqlParameter>());
    foreach (DataRow dr in dt.Rows)
    {
        dataColumns.Add(new dataColumnSpecs(dr["columnName"].ToString(), dr["friendlyName"].ToString(), dr["dataType"].ToString(), (int)dr["dataSize"]));
    }
}

public void fillDDLColumns()
{
    fillDataColumnsList();
    ddlColumns.Items.Clear();
    foreach (dataColumnSpecs dcs in dataColumns) 
    { 
        ListItem li = new ListItem(); 
        li.Text = dcs.friendlyName; 
        li.Value = dcs.columnName; 
        ddlColumns.Items.Add(li);
    }
    ddlColumns.Items.Insert(0, new ListItem(" -SELECT A COLUMN- ", ""));
    ddlColumns.DataBind();  
}

protected void ddlColumns_SelectedChanged(object sender, EventArgs e)
{
    //THIS CODE IS BEING FIRED WHEN A BUTTON ON THE PARENT *.ASPX IS CLICKED
}

* .ASPX

<asp:UpdatePanel ID="upControls" runat="server">
    <ContentTemplate>
        <asp:Button ID="btnAddControl" runat="server" Text="+" OnClick="btnAddControl_Click" />
    </ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnGo" runat="server" Text="Go" OnClick="btnGo_Click" ValidationGroup="vgGo" />
<asp:GridView...

* .ASPX.CS

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        uc_Counter = 0;
        addControl();
        gridview_DataBind();
    }
    else
    {
        reloadControls();
    }
}

protected void btnGo_Click(object sender, EventArgs e)
{
    if (Page.IsValid)
    {
        //THIS BUTTON CLICK IS WHAT'S TRIGGERING THE 
        //SELECTEDINDEXCHANGED EVENT TO FIRE ON MY *.ASCX
        gridview_DataBind();
    }   
}

private void reloadControls()
{
    int count = this.uc_Counter;

    for (int i = 0; i < count; i++)
    {
        Control myUserControl = Page.LoadControl("~/Controls/myUserControl.ascx");
        myUserControl.ID = "scID_" + i;
        upControls.ContentTemplateContainer.Controls.AddAt(i, myUserControl);
        ((customUserControl)myUserControl).fillDDLColumns();
    }
}

private void addControl()
{
    Control myUserControl = Page.LoadControl("~/Controls/myUserControl.ascx");
    myUserControl.ID = "scID_" + uc_Counter.ToString();
    upControls.ContentTemplateContainer.Controls.AddAt(upControls.ContentTemplateContainer.Controls.IndexOf(btnAddControl), myUserControl);            
    //((customUserControl)myUserControl).fillDDLColumns();
    this.uc_Counter++;
}

protected int uc_Counter
{
    get { return (int)ViewState["uc_Counter"]; }
    set { ViewState["uc_Counter"] = value; }
}
4

2 回答 2

1

尽管这已经得到解答,但我想在这里给出一个答案,因为我最近纠结于这个问题,我无法在任何地方找到对我有帮助的答案,但在大量挖掘代码后我确实找到了解决方案。

对我来说,发生这种情况的原因是有人覆盖了 PageStatePersister 以更改视图状态隐藏字段的呈现方式。为什么要这样做?我在这里找到了答案。

尝试优化 ASP.NET 页面以使其对搜索引擎更加友好时,最大的问题之一是视图状态隐藏字段。大多数搜索引擎对文档的第一个 [原文如此] 数千字节的内容给予更高的分数,因此如果您的前 2 KB 是查看状态垃圾,那么您的页面将受到惩罚。所以这里的目标是尽可能地向下移动视图状态数据。

我遇到的代码所做的是将 __VIEWSTATE 隐藏字段清空并在页面底部创建一个 view_state 隐藏字段。这样做的问题是它完全弄乱了视图状态,并且我收到报告为下拉列表被更改时,它们没有被更改,并且所有下拉列表在提交时都通过相同的处理程序。这是一团糟。我的解决方案是仅在此页面上关闭此自定义持久性,这样我就不必补偿所有这些怪异之处。

protected override PageStatePersister PageStatePersister
{
    get
    {
        if (LoginRedirectUrl == "/the_page_in_question.aspx")
        {
            return new HiddenFieldPageStatePersister(Page);
        }
        return new CustomPageStatePersister(this);
    }
}

这使我能够对需要它的页面拥有正确的视图状态,但保留网站其余部分的 SEO 代码。希望这可以帮助某人。

于 2016-01-12T21:25:42.370 回答
0

我在这篇文章中找到了我的答案.net DropDownList 在回发后被清除

我将存储在视图状态中的计数器更改为会话变量。然后我将我的 reloadControls() 函数从 *.ASPX 的 Page_Load 移动到 Page_Init。

关键是在 Page_Init 中动态添加我的用户控件,以便在将 Viewstate 应用于页面上的控件之前,它将成为页面的成员。

于 2012-05-31T16:53:06.277 回答