我需要最初基于相当多的处理器和磁盘密集型搜索来生成按钮.每个按钮代表一个选择并触发回发.我的问题是回发不会触发命令b_Command.我猜是因为没有重新创建原始按钮.我无法在回发中执行原始搜索以重新创建按钮,因此我想从回发信息生成所需的按钮.
我该怎么做以及在哪里做这个?我应该在Page_Load之前做这件事吗?如何从回发中重新构造CommandEventHandler - 如果有的话?
namespace CloudNavigation { public partial class Test : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { // how can I re-generate the button and hook up the event here // without executing heavy search 1 } else { // Execute heavy search 1 to generate buttons Button b = new Button(); b.Text = "Selection 1"; b.Command += new CommandEventHandler(b_Command); Panel1.Controls.Add(b); } } void b_Command(object sender, CommandEventArgs e) { // Execute heavy search 2 to generate new buttons Button b2 = new Button(); b2.Text = "Selection 2"; b2.Command += new CommandEventHandler(b_Command); Panel1.Controls.Add(b2); } } }
JohnIdol.. 5
b_Command事件处理程序方法未被执行,因为没有重新创建回发按钮(因为它们是动态生成的).每次重新创建页面时都需要重新创建它们,但为了做到这一点,您需要在状态中的某处显式地缓存信息.
如果这是一个页面范围操作最简单的方法是将它存储在ViewState中(作为字符串 - 如果你开始用对象加载ViewState,你会看到性能下降),这样你就可以在下次加载时检查它(或任何其他的事件)并在重新加载页面时重新创建按钮.如果操作是会话范围的,您可以轻松地在会话中存储对象(数组或其他)并在下一个Load(或Init)上检索它以重新创建控件.
这种情况意味着您只需要在b_Command EventHandler中存储有关按钮的一些信息,而不是创建和添加按钮,因为如果这样做,您将在下一次回发中丢失相关信息(现在正在发生).
所以你的代码会变成这样的:
namespace CloudNavigation { public partial class Test : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { this.recreateButtons(); } else { // Execute heavy search 1 to generate buttons Button b = new Button(); b.Text = "Selection 1"; b.Command += new CommandEventHandler(b_Command); Panel1.Controls.Add(b); //store this stuff in ViewState for the very first time } } void b_Command(object sender, CommandEventArgs e) { //Execute heavy search 2 to generate new buttons //TODO: store data into ViewState or Session //and maybe create some new buttons } void recreateButtons() { //retrieve data from ViewState or Session and create all the buttons //wiring them up to eventHandler } } }
如果您不想在页面加载时调用recreateButtons,您可以在PreLoad或Init事件上执行它,我没有看到区别,因为您将能够到处访问ViewState/Session变量(在Init viewstate上未应用)但您可以访问它来重新创建动态按钮).
有人会讨厌这个解决方案,但据我所知,保留状态数据服务器端的唯一方法是ViewState - Session - Page.Transfer或客户端cookie.
b_Command事件处理程序方法未被执行,因为没有重新创建回发按钮(因为它们是动态生成的).每次重新创建页面时都需要重新创建它们,但为了做到这一点,您需要在状态中的某处显式地缓存信息.
如果这是一个页面范围操作最简单的方法是将它存储在ViewState中(作为字符串 - 如果你开始用对象加载ViewState,你会看到性能下降),这样你就可以在下次加载时检查它(或任何其他的事件)并在重新加载页面时重新创建按钮.如果操作是会话范围的,您可以轻松地在会话中存储对象(数组或其他)并在下一个Load(或Init)上检索它以重新创建控件.
这种情况意味着您只需要在b_Command EventHandler中存储有关按钮的一些信息,而不是创建和添加按钮,因为如果这样做,您将在下一次回发中丢失相关信息(现在正在发生).
所以你的代码会变成这样的:
namespace CloudNavigation { public partial class Test : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { this.recreateButtons(); } else { // Execute heavy search 1 to generate buttons Button b = new Button(); b.Text = "Selection 1"; b.Command += new CommandEventHandler(b_Command); Panel1.Controls.Add(b); //store this stuff in ViewState for the very first time } } void b_Command(object sender, CommandEventArgs e) { //Execute heavy search 2 to generate new buttons //TODO: store data into ViewState or Session //and maybe create some new buttons } void recreateButtons() { //retrieve data from ViewState or Session and create all the buttons //wiring them up to eventHandler } } }
如果您不想在页面加载时调用recreateButtons,您可以在PreLoad或Init事件上执行它,我没有看到区别,因为您将能够到处访问ViewState/Session变量(在Init viewstate上未应用)但您可以访问它来重新创建动态按钮).
有人会讨厌这个解决方案,但据我所知,保留状态数据服务器端的唯一方法是ViewState - Session - Page.Transfer或客户端cookie.