[英]selectedIndex is lost during postbacks - ASP.NET
我有一個列表框控件:
<asp:ListBox runat="server" id="lbox" autoPostBack="true" />
背后的代碼類似於:
private void Page_Load(object sender, System.EventArgs e)
{
lbox.SelectedIndexChanged+=new EventHandler(lbox_SelectedIndexChanged);
if(!Page.IsPostBack)
{
LoadData();
}
}
private LoadData()
{
lbox.DataSource = foo();
lbox.DataBind();
}
protected void lboxScorecard_SelectedIndexChanged(object sender, EventArgs e)
{
int index = (sender as ListBox).selectedIndex;
}
我的問題是,當我的頁面收到回發帖子時(當用戶在列表框中進行選擇時),選擇總是“跳轉”到列表框中的第一個項目,因此我的回調函數中的索引變量始終為0。
這似乎可能是一個viewstate問題? 如何修復它以便選擇索引保留在回發中?
沒有ajax,這是.NET 1.0。
謝謝。
編輯1 JohnIdol讓我更近了一步,如果我將數據源從我原來的DataTable切換到ArrayList,那么一切正常......會導致什么?
編輯2事實證明我的DataTable有多個相同的值,因此索引被視為具有相同值的所有項目相同...感謝那些幫助過的人!
這里真正的問題是事件的順序。 當您在page_load中進行數據綁定時,會覆蓋已發布的數據,這就是為什么未在列表框中設置選擇的原因。 您可以通過將綁定邏輯移動到Page_Init來輕松克服此問題。
foo()函數調用的輸出是什么?
手動填充列表框,您可以將索引設置為您想要的任何內容(例如全部為0) - 因此在某些情況下設置給定的dataSource會發生同樣的事情(一個指定我認為的索引)。 如果所有項索引都為0,則結果是不會引發SelectedIndexChanged事件(索引不會更改!)並且所有內容都搞亂了:在回發后選擇將返回到列表中的第一項。
這可以解釋它 - 我無法想到其他任何東西 - 它在.NET 2.0上運行正常我正在使用帶有字符串的ArrayList來填充listBox。
我可以重現您的問題的唯一方法是將所有索引設置為0。
我會說在ListBox中添加一個監視並在運行時檢查索引以確保它們不是全零。
如果您的列表框項目相同,則所選索引將設置為0.要糾正它,將不同的值設置為item.value
並讓item.text
保持不變..然后選擇的索引將正確顯示。
數據綁定DropDownLists / ListBox是很痛苦的,因為它們經常綁定到錯誤的值。
我已經放棄使用DataBind(),只是使用Foreach循環:
foreach (Item i in DataSet)
{
listBox.Items.Add(etc);
}
將數據加載到Page_Init而不是Page_Load。 在Page_init期間必須填充數據以便在PostBack中可用。
在我看來,你正在為每個頁面加載創建一個新的事件處理程序。 這可能會導致問題。 為什么不以聲明方式附加事件處理程序:
<asp:ListBox runat="server" id="lbox" autoPostBack="true" OnSelectedIndexChanged="lbox_SelectedIndexChanged" />
另外,為什么不直接引用控件而不是鑄造?
protected void lbox_SelectedIndexChanged(object sender, EventArgs e)
{
int index = lbox.selectedIndex;
}
也適合我。 你的foo()每次都返回相同的值嗎?
正如旁注:如果可能的話,你應該在OnInit中進行數據綁定(每次都是在GET上)。 如果你在調用base.OnInit(...)之前這樣做,你的列表框的內容將不必序列化和反序列化到viewstate和通過線路發送到客戶端(是的,你將會命中數據庫更多,但你將會遇到位於本地子網上的系統,甚至是同一台機器上的系統。此外,數據庫可能會緩存結果)。
如果要構建高性能網站,則需要仔細查看使用ViewState的方式。 我強烈推薦這篇文章: TRULY了解ViewState
您是否考慮過提前加載數據 - 例如在頁面/用戶控件上的OnInit事件中。 這是在加載回發數據之前發生的,因此可以在處理變更之前進行? 我相信這應該有用 - 但你可能想要關閉viewstate!
我不知道它是否有所作為,但我通常將我的控件附加到首頁上的事件而不是代碼隱藏中。 在你的例子中,我會做:
<asp:ListBox runat="server" id="lbox" autoPostBack="true" OnSelectedIndexChanged="lboxScorecard_SelectedIndexChanged" />
除此之外,我將驗證ViewState是否已啟用。 可以在控件,頁面甚至站點級別調整ViewState。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.