Итак, у меня странная ситуация ... У меня есть класс System.Web.UI.WebControls.WebParts.EditorPart. Он отображает кнопку «Поиск», когда вы нажимаете эту кнопку, метод clickHandler выполняет поиск в БД и динамически создает LinkButton для каждой возвращаемой строки, устанавливает свойства CommandName и CommandArgument и добавляет метод CommandEventHandler, а затем добавляет элемент управления LinkButton. на страницу.
Проблема в том, что когда вы нажимаете LinkButton, его метод CommandEventHandler никогда не вызывается, похоже, что страница просто отправляет обратно туда, где она была до нажатия ОРИГИНАЛЬНОЙ кнопки «Поиск».
Я видел сообщения, в которых говорилось, что вам нужно добавить обработчики событий в OnLoad () или какой-либо другой ранний метод, но мои LinkButtons даже не были созданы, пока пользователь не скажет нам, что искать, и не нажмет кнопку «Поиск». . Есть идеи, как с этим бороться?
Спасибо!





Вам необходимо повторно добавить динамически созданные элементы управления в onload, чтобы они могли находиться в иерархии страниц и запускать свое событие.
Это мой любимый трюк :)
Наш сценарий состоит в том, чтобы сначала отобразить элемент управления. Затем, используя некоторый ввод от пользователя, визуализируйте дополнительные элементы управления и заставьте их реагировать на события.
Ключевым моментом здесь является состояние - вам нужно знать состояние элемента управления, когда он поступает в 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]);
}
Это похоже на крутой трюк, еще не пробовал (этот проект приостановлен), но похоже, что он сработает. Кроме того, теперь, когда мы НАКОНЕЦ установили 3.5 в этой среде, вы, вероятно, также можете просто поместить кнопку поиска в UpdatePanel и вместо этого сделать все это с частичной обратной передачей страницы.
Грязный прием, который я только что придумал, заключается в создании фиктивных LinkButtons с теми же идентификаторами, что и настоящие кнопки. Итак, предположим, вы собираетесь создать LinkButton «foo» в Pre_Render (что уже слишком поздно), а затем также создать фиктивный foo в Page_Load:
var link = new LinkButton();
link.ID = "foo";
link.Click += fooEventHandler;
dummyButtons.Controls.Add(link);
(Где «dummyButtons» - это просто PlaceHolder на странице с параметром Visibility, установленным на false.) Это некрасиво, но работает.
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
{
}
}
Проблема в том, что я не буду знать, сколько мне нужно сделать, пока запрос не будет выполнен ... Единственное решение, которое также может выполнять запрос внутри createchildcontrols?