在事件处理程序以外的代码隐藏部分中确定所选索引是否已更改或是否触发了自动回发事件

Determine whether the selected index was changed or an autopostback event was triggered, in sections of the code-behind other than the event handler

我有一个 ASP DropDownList 控件,其 AutoPostBack 属性 设置为 true。当用户更改选择时,表单会按预期回发。我想知道如何在代码隐藏中确定页面是否由于这个特定原因而回发。


我知道我可以定义这样的事件处理程序...

protected void MyDropDownList_SelectedIndexChanged(object sender, EventArgs e) {
    // Run some code if the selection for the "MyDropDownList" control was changed
}

...但我想知道的是如何检查表单回发是否因为所选索引在事件处理程序之外发生了更改。

具体来说,在Page_Load()方法中,我有一个if (IsPostback) {}部分,我希望这个部分 如果回发是由更改 DropDownList 中的选择引起的,则执行。所以,在伪代码中,我想要这样的东西:

if (IsPostback && (! <DropDownList's selection was changed, causing an autopostback>)) {

我尝试定义一个全局布尔变量并在事件处理程序中将其设置为 true,然后在 Page_Load(),像这样:

public partial class MyWebApp : System.Web.UI.Page {
    [...]
    static bool selectedIndexChanged = false;
    [...]
    protected void DomainDropDownList_SelectedIndexChanged(object sender, EventArgs e) {
        selectedIndexChanged = true; // Set this flag to true if selected index was changed
    }
    [...]
    protected void Page_Load(object sender, EventArgs e) {
    [...]
        if (IsPostBack && selectedIndexChanged == false) { 
            [...]
        }
        [...]

由于我认为有经验的 ASP.NET 开发人员会很容易发现的原因,这不起作用:事件处理程序在 Page_Load() 之后执行,无论代码的顺序。

我也试过看看控件的selectedIndexChanged事件是否可以作为布尔条件判断事件是否触发,像这样

if (IsPostBack && !MyDropDownList.SelectedIndexChanged) {

但是 Visual Studio 给我以下错误:

The event 'System.Web.UI.WebControls.ListControl.SelectedIndexChanged' can only appear on the left hand side of += or -="

对错误消息的搜索导致 this answer,但这似乎没有帮助,因为它依赖于在 Page_Load() 之后执行的事件处理程序.

在我的特定用例中,只有一个 DropDownList 并且只有一种提交表单的其他方式(提交按钮),检查所选索引是否已更改、AutoPostBack 是否已更改同样有效触发,或者提交按钮是否被点击,但我也想知道如何在更广泛的场景中执行此操作,例如,如果有多个 AutoPostBack 控件 and/or 除了提交表单之外的多种方式自动回发。


因此,我的问题分解如下(尽管其中一些可能本质上是相同的问题,具体取决于答案是什么):

如果有更好的方法来实现我在这种特殊情况下想要实现的目标,我愿意接受建议,但我仍然想知道上述问题的答案。

Page_Load 期间检查 Page.Request.Form["__EVENTTARGET"]。这将包含一个标识符,表示导致 post 返回的控件。由此您应该能够确定 post 返回是否是由您感兴趣的控件引起的。

if (IsPostBack && Request.Form["__EVENTTARGET"] != "<control ID>") {
    ...
}

Is it possible to check in the Page_Load() method or any other code that executes before the SelectedIndexChanged event handler whether a DropDownList's selected index was changed?

不是没有诉诸自定义技术。 SelectedIndexChanged 事件在 page event lifecycle 期间触发得太晚,无法用于您的场景。一种选择是在 Page.OnPreRender 期间将 DropDownList.SelectedIndex 存储到 Page.ViewState 集合中,然后在 [=11] 期间将此值与 post 上的新 DropDownList.SelectedIndex 进行比较=].