所以我这里有一个奇怪的情况...我有一个 System.Web.UI.WebControls.WebParts.EditorPart 类。它呈现一个“搜索”按钮,当您单击此按钮时,它的 clickHandler 方法执行数据库搜索,并为其返回的每一行动态创建一个 LinkButton,设置 CommandName 和 CommandArgument 属性并添加一个 CommandEventHandler 方法,然后添加 LinkButton 控件到页面。
问题是,当您单击 LinkButton 时,它的 CommandEventHandler 方法永远不会被调用,看起来页面只是返回到按下原始“搜索”按钮之前的位置。
我看到帖子说您需要在 OnLoad() 或其他一些早期方法中添加事件处理程序,但直到用户告诉我们要搜索的内容并点击“搜索”,我的 LinkButton 才被创建按钮...关于如何处理这个的任何想法?
谢谢!
最佳答案
这是我最喜欢的技巧:)
我们的场景是先渲染一个控件。然后使用来自用户的一些输入,呈现进一步的控件并让它们响应事件。
这里的关键是状态——你需要知道控件到达 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]);
}
关于C# 动态创建的 LinkButton 命令事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/141169/