3

所以我在这里遇到了一个奇怪的情况......我有一个 System.Web.UI.WebControls.WebParts.EditorPart 类。它呈现一个“搜索”按钮,当您单击此按钮时,它的 clickHandler 方法会进行 DB 搜索,并为它返回的每一行动态创建一个 LinkBut​​ton,设置 CommandName 和 CommandArgument 属性并添加一个 CommandEventHandler 方法,然后添加 LinkBut​​ton 控件到页面。

问题是,当您单击 LinkBut​​ton 时,它的 CommandEventHandler 方法永远不会被调用,看起来页面只是返回到按下原始“搜索”按钮之前的位置。

我看到帖子说您需要在 OnLoad() 或其他一些早期方法中添加事件处理程序,但是直到用户告诉我们要搜索什么并点击“搜索”按钮之前,我的 LinkBut​​tons 甚至还没有创建。 .关于如何处理这个的任何想法?

谢谢!

4

4 回答 4

3

这是我最喜欢的把戏:)

我们的场景是首先渲染一个控件。然后使用来自用户的一些输入,呈现更多控件并让它们响应事件。

这里的关键是状态——你需要知道控件到达 PostBack 时的状态——所以我们使用 ViewState。那么问题就变成了先有鸡还是先有蛋的问题。ViewState 在调用之后才可用LoadViewState(),但您必须在调用之前创建控件才能正确触发事件。

诀窍是覆盖LoadViewState()SaveViewState()因此我们可以控制事物。

(请注意,下面的代码是粗略的,来自记忆,可能有问题)

private string searchQuery = null;

private void SearchButton(object sender, EventArgs e)
{
    searchQuery = searchBox.Text;
    var results = DataLayer.PerformSearch(searchQuery);
    CreateLinkButtonControls(results);
}

// We save both the base state object, plus our query string.  Everything here must be serializable.
protected override object SaveViewState()
{
    object baseState = base.SaveViewState();
    return new object[] { baseState, searchQuery };
}

// The parameter to this method is the exact object we returned from SaveViewState().
protected override void LoadViewState(object savedState)
{
    object[] stateArray = (object[])savedState;

    searchQuery = stateArray[1] as string;

    // Re-run the query
    var results = DataLayer.PerformSearch(searchQuery);

    // Re-create the exact same control tree as at the point of SaveViewState above.  It must be the same otherwise things will break.
    CreateLinkButtonControls(results);

    // Very important - load the rest of the ViewState, including our controls above.
    base.LoadViewState(stateArray[0]);
}
于 2008-10-14T14:10:05.363 回答
1

您需要在 onload 中重新添加动态创建的控件,以便它们可以在页面层次结构中并触发它们的事件。

于 2008-09-26T18:42:26.163 回答
0
 LinkButton link= new LinkButton();
 link.Command +=new CommandEventHandler(LinkButton1_Command);

 protected void LinkButton1_Command(object sender, CommandEventArgs e)
{
    try
    {
        System.Threading.Thread.Sleep(300);
        if (e.CommandName == "link")
        {
           //////////
        }
    }
    catch
    {

    }
}
于 2017-01-11T11:25:05.147 回答
-1

我刚刚想出的一个肮脏的技巧是创建与真实按钮具有相同 ID 的虚拟 LinkBut​​tons。因此,假设您要在 Pre_Render 创建一个 LinkBut​​ton“foo”(为时已晚),然后还要在 Page_Load 创建一个虚拟 foo:

        var link = new LinkButton();
        link.ID = "foo";
        link.Click += fooEventHandler;
        dummyButtons.Controls.Add(link);

(其中“dummyButtons”只是页面上的一个 PlaceHolder,Visibility 设置为 false。)它很丑,但它有效。

于 2010-04-01T09:26:39.753 回答