1

カスタムユーザーコントロールを更新パネルに動的に追加しています。私のユーザーコントロールには、2つのドロップダウンリストと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ページを最適化して検索エンジンに適したものにしようとする場合の最大の問題の1つは、ビューステートの非表示フィールドです。ほとんどの検索エンジンは、ドキュメントの最初の数千バイトのコンテンツにより多くのスコアを与えるため、最初の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

私はこの投稿で私の答えを見つけました.netDropDownListはポストバック後にクリアされます

ビューステートに格納していたカウンターをセッション変数に変更しました。次に、reloadControls()関数を*.ASPXのPage_LoadからPage_Initに移動しました。

重要なのは、Page_Initにユーザーコントロールを動的に追加して、ビューステートがページのコントロールに適用される前にページのメンバーになるようにすることでした。

于 2012-05-31T16:53:06.277 に答える