所以我有一个奇怪的情况......我有一个System.Web.UI.WebControls.WebParts.EditorPart类。它呈现一个“搜索”按钮,当你单击这个按钮时,它的clickHandler方法进行数据库搜索,并为它返回的每一行动态创建一个LinkButton,设置CommandName和CommandArgument属性并添加一个CommandEventHandler方法,然后添加LinkButton控件到页面。
问题是,当你单击一个LinkButton时,它的CommandEventHandler方法永远不会被调用,看起来该页面只是回复到按下ORIGINAL“搜索”按钮之前的位置。
我看到帖子说你需要在OnLoad()或其他一些早期方法中添加事件处理程序,但是在用户告诉我们要搜索什么并点击“搜索”之前,我的LinkButtons甚至都没有创建过。按钮......关于如何处理这个的任何想法?
谢谢!
答案 0 :(得分:3)
这是我最喜欢的技巧:)
我们的场景是首先渲染一个控件。然后使用来自用户的一些输入,渲染进一步的控件并让它们响应事件。
这里的关键是状态 - 当它到达PostBack时你需要知道控件的状态 - 所以我们使用ViewState。这个问题就变成了鸡与蛋的问题;在LoadViewState()
调用之后,ViewState才可用,但您必须在调用之前创建控件才能正确触发事件。
诀窍是覆盖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]);
}
答案 1 :(得分:1)
您需要在onload中重新添加动态创建的控件,以便它们可以位于页面层次结构中并触发其事件。
答案 2 :(得分: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
{
}
}
答案 3 :(得分:-1)
我刚想出的一个肮脏的黑客,是创建与真实按钮具有相同ID的虚拟LinkButtons。 所以假设你要在Pre_Render创建一个LinkButton“foo”(为时已晚),然后在Page_Load创建一个虚拟foo:
var link = new LinkButton();
link.ID = "foo";
link.Click += fooEventHandler;
dummyButtons.Controls.Add(link);
(其中“dummyButtons”只是Visibility设置为false的页面上的PlaceHolder。) 这很难看,但它确实有效。