Это мой любимый трюк:)
Наш сценарий - сначала сделать элемент управления. Затем, используя некоторые входные данные от пользователя, визуализируйте дополнительные элементы управления и заставьте их реагировать на события.
Ключевым моментом здесь является состояние - вам нужно знать состояние элемента управления, когда он поступает в 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]);
}