在回发期间,selectedIndex丢失了 - ASP.NET

时间:2008-12-03 19:49:07

标签: c# .net asp.net viewstate

我有一个列表框控件:


<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有多个相同的值,因此索引被视为与具有相同值的所有项目相同...感谢那些帮助过的人!

9 个答案:

答案 0 :(得分:10)

此处真实问题是事件顺序。当您在page_load中进行数据绑定时,会覆盖已发布的数据,这就是为什么未在列表框中设置选择的原因。您可以通过将绑定逻辑移动到Page_Init来轻松解决此问题。

答案 1 :(得分:2)

foo()函数调用的输出是什么?

手动填充列表框,您可以将索引设置为您想要的任何内容(例如全部为0) - 因此在某些情况下设置给定的dataSource会发生同样的事情(一个指定我认为的索引)。如果所有项索引都为0,则结果是不会引发SelectedIndexChanged事件(索引不会更改!)并且所有内容都搞乱了:在回发后选择将返回到列表中的第一项。

这可以解释它 - 我想不出别的 - 它在.NET 2.0上运行正常我使用带有字符串的ArrayList来填充listBox。

我可以重现您的问题的唯一方法是将所有索引设置为0。

我想在ListBox中添加一个监视并在运行时检查索引以确保它们不是全为零。

答案 2 :(得分:2)

如果您的列表框项目相同,则所选索引将设置为0.要纠正它,将不同的值设置为item.value并让item.text保持不变..然后选择的索引将正确显示

答案 3 :(得分:1)

数据绑定DropDownLists / ListBox是很痛苦的,因为它们经常绑定到错误的值。

我已经放弃使用DataBind(),只是使用Foreach循环:

foreach (Item i in DataSet)
{
     listBox.Items.Add(etc);
}

答案 4 :(得分:1)

将数据加载到Page_Init而不是Page_Load。必须在Page_init期间填充数据,以便在PostBack中可用。

答案 5 :(得分:0)

在我看来,您正在为每个页面加载创建一个新的事件处理程序。这可能会导致问题。为什么不以声明方式附加事件处理程序:

<asp:ListBox runat="server" id="lbox" autoPostBack="true" OnSelectedIndexChanged="lbox_SelectedIndexChanged" />

另外,为什么不直接引用控件而不是转换?

protected void lbox_SelectedIndexChanged(object sender, EventArgs e)
{
    int index = lbox.selectedIndex;
}

答案 6 :(得分:0)

也适合我。你的foo()每次都返回相同的值吗?

正如旁注:如果可能的话,你应该在OnInit中进行数据绑定(每次都在GET上)。如果你在调用base.OnInit(...)之前这样做,你的列表框的内容将不必序列化和反序列化到viewstate和通过线路发送到客户端(是的,你将会命中数据库更多,但你将会遇到位于本地子网上的系统,甚至是同一台机器上的系统。此外,数据库可能会缓存结果)。

如果您想构建高性能网站,则需要仔细查看使用ViewState的方式。我强烈推荐这篇文章:TRULY Understanding ViewState

答案 7 :(得分:-1)

您是否考虑过提前加载数据 - 例如在页面/用户控件上的OnInit事件中。这是在加载回发数据之前发生的,因此可以在处理变更之前进行?我相信这应该有用 - 但你可能想要关闭viewstate!

答案 8 :(得分:-2)

我不知道它是否有所作为,但我通常将我的控件附加到首页上的事件而不是代码隐藏中。在你的例子中我会做:

<asp:ListBox runat="server" id="lbox" autoPostBack="true" OnSelectedIndexChanged="lboxScorecard_SelectedIndexChanged"  />

除此之外,我将验证ViewState是否已启用。可以在控件,页面和&amp;处打开ViewState。甚至网站级别。