5

我有一个列表框控件:


<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。

看起来这可能是一个视图状态问题?如何修复它以使选择索引通过回发保持不变?

没有 ajax,这是 .NET 1.0。

谢谢。

编辑 1 JohnIdol 让我更近了一步,如果我将数据源从原来的 DataTable 切换到 ArrayList,那么一切正常......会导致这种情况吗?

编辑 2事实证明,我的 DataTable 有多个相同的值,因此索引被视为与具有相同值的所有项目相同......感谢那些帮助的人!

4

9 回答 9

10

这里真正的问题是事件的顺序。当您在 page_load 中进行数据绑定时,您会覆盖发布的数据,这就是未在列表框中设置选择的原因。您可以通过将绑定逻辑移至 Page_Init 轻松克服这个问题。

于 2008-12-10T19:12:21.983 回答
2

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

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

这可以解释它 - 我想不出其他任何东西 - 它在 .NET 2.0 上对我来说工作正常我正在使用带有字符串的 ArrayList 来填充 listBox。

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

我会说向 ListBox 添加一个手表并在运行时检查索引以确保它们不全为零。

于 2008-12-03T20:39:49.520 回答
2

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

于 2011-11-24T08:59:56.417 回答
1

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

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

foreach (Item i in DataSet)
{
     listBox.Items.Add(etc);
}
于 2008-12-03T21:09:56.213 回答
1

在 Page_Init 而不是 Page_Load 中加载数据。必须在 Page_init 期间填充数据才能在 PostBack 中使用。

于 2011-06-29T22:47:03.823 回答
0

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

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

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

protected void lbox_SelectedIndexChanged(object sender, EventArgs e)
{
    int index = lbox.selectedIndex;
}
于 2008-12-03T20:04:29.170 回答
0

也为我工作。您的 foo() 是否每次都返回相同的值?

顺便说一句:如果可能,您应该真正在 OnInit 中进行数据绑定(每次,而不仅仅是在 GET 上)。如果您在调用 base.OnInit(...) 之前执行此操作,则列表框的内容不必在视图状态和视图状态之间进行序列化和反序列化并通过线路发送到客户端(是的,您将点击数据库更多,但您将访问位于本地子网甚至同一台计算机上的系统。此外,数据库可能会缓存结果)。

如果你想构建高性能的网站,你需要仔细看看你使用 ViewState 的方式。我强烈推荐这篇文章:真正理解 ViewState

于 2008-12-03T21:08:33.220 回答
-1

您是否考虑过更早地加载数据 - 例如在页面/用户控件上的 OnInit 事件中。这发生在加载回发数据之前,因此在可以处理 on-change 之前?我相信这应该可行 - 但您可能想要关闭视图状态!

于 2008-12-03T20:24:28.957 回答
-2

我不知道它是否有区别,但我通常将我的控件附加到首页上的事件而不是代码隐藏中。在您的示例中,我会这样做:

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

除此之外,我会验证 ViewState 是否已启用。ViewState 可以在控件、页面甚至站点级别关闭。

于 2008-12-03T20:00:10.427 回答