在 AJAX UpdatePanel 中获取触发 postback 的 ASP.NET 控件

4

与这个问题相关:在PostBack时,如何在Page_Init事件中检查哪个控件引起PostBack

如果控件被包含在ASP.NET AJAX UpdatePanel中,“control”变量是空的,因为它在AJAX PostBack后有不同的ID。是否有解决方案可以在ASP.NET Ajax UpdatePanel内获取触发Postback的控件?

public static string GetPostBackControlName( Page page ) {
        Control control = null;

        /**
         * First we will check the "__EVENTTARGET" because if the postback is made
         * by controls which used the _doPostBack function, it will be available in the Request.Form collection.
         */
        string ctrlname = page.Request.Params["__EVENTTARGET"];

        if ( !String.IsNullOrEmpty( ctrlname ) ) {
            control = page.FindControl( ctrlname );
        } else {
            /**
             * If __EVENTTARGER is null, the control is a button-type and
             * need to iterate over the form collection to find it.
             */
            Control c = null;
            string ctrlStr = null;

            foreach ( string ctl in page.Request.Form ) {
                if ( ctl.EndsWith( ".x" ) || ctl.EndsWith( ".y" ) ) {
                    /**
                     * ImageButtons have an additional "quasi-property" in their ID which identifies
                     * the mouse-coordinates (X and Y).
                     */
                    ctrlStr = ctl.Substring( 0, ctl.Length - 2 );
                    c = page.FindControl( ctrlStr );
                } else {
                    c = page.FindControl( ctl );
                }

                if ( c is Button || c is ImageButton ) {
                    control = c;
                    break;
                }
            }
        }

        if ( control != null ) {
            return control.ID;
        }

        return string.Empty;
    }
3个回答

9
请尝试以下方法:
public string GetAsyncPostBackControlID()
{
    string smUniqueId = ScriptManager.GetCurrent(Page).UniqueID;
    string smFieldValue = Request.Form[smUniqueId];

    if (!String.IsNullOrEmpty(smFieldValue) && smFieldValue.Contains('|'))
    {
        return smFieldValue.Split('|')[1];
    }

    return String.Empty;
}

上述方法使用页面上ScriptManager的隐藏字段。可以通过搜索具有ScriptManager的UniqueID的表单键来访问它的值。隐藏字段中的值格式为[UpdatePanel UniqueID]|[Postback Control ID]。了解这些信息,我们可以检索启动异步回发的控件的ID。同时,此方法也适用于提交按钮。


不错!只是代码有一个非常小的更新;.Contains('|')应该是.Contains("|") :o) - thomasvdb

1
这是@bugventure在VB.NET中的代码...通过添加一个页面引用作为参数进行修改,以便我可以在通用库中使用它。
Public Function GetAsyncPostBackControlID(ByRef page As Page) As String
        Dim smUniqueId As String = ScriptManager.GetCurrent(page).UniqueID
        Dim smFieldValue As String = page.Request.Form(smUniqueId)

        If Not String.IsNullOrEmpty(smFieldValue) AndAlso smFieldValue.Contains("|") Then
            Return smFieldValue.Split("|")(1)
        End If

        Return String.Empty
End Function

使用方法:

' Call from a control or Page
Dim postbackControlID As String = GetAsyncPostBackControlID(Page)

' Call from a page
Dim postbackControlID As String = GetAsyncPostBackControlID(Me)

你传递了什么参数给这个方法?在bugventure的帖子中,他的方法没有接受任何参数。 - sab669
1
我传递一个对Page对象的引用。这是为了使该函数可以在公共库中使用。在Bugventure版本中,页面引用使用Control.Page属性检索,该属性存储对包含控件的页面的引用。当在页面内调用此属性时,它指向自身,并且与使用“Me”相同。我将添加一个用法示例。 - Joe Niland
哦,谢谢。我是VB开发的新手,所以我不确定“Me”是否正确。 - sab669

0

要获取导致异步回发的控件,您可以使用以下方法而不是解析

var scriptManager = ScriptManager.GetCurrent(Page);
var asyncPostBackSourceControl = Page.FindControl(scriptManager.AsyncPostBackSourceElementID);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接