Программно добавить UserControl с событиями - PullRequest
0 голосов
/ 14 декабря 2009

Мне нужно добавить несколько пользовательских элементов управления на панель для дальнейшего редактирования содержащихся данных. Мой пользовательский элемент управления содержит несколько панелей, раскрывающихся списков и элементов ввода, которые заполняются в событии Page_Load пользовательского элемента управления.

protected void Page_Load(object sender, EventArgs e)
{
  // populate comparer ddl from enum
  string[] enumNames = Enum.GetNames(typeof (SearchComparision));

  var al = new ArrayList();
  for (int i = 0; i < enumNames.Length; i++)
    al.Add(new {Value = i, Name = enumNames[i]});

  scOperatorSelection.DataValueField = "Value";
  scOperatorSelection.DataTextField = "Name";
  ...

Данные для отображения добавляются в пользовательский элемент управления в виде поля, определенного выше Page_Load. Подпись событий следующая:

public delegate void ControlStateChanged(object sender, SearchCriteriaEventArgs eventArgs);

public event ControlStateChanged ItemUpdated;
public event ControlStateChanged ItemRemoved;
public event ControlStateChanged ItemAdded;

Кнопка обновления на пользовательском элементе управления запускает следующий метод:

protected void UpdateCriteria(object sender, EventArgs e)
{
  var searchCritCtl = (SearchCriteria) sender;

  var scEArgs = new SearchCriteriaEventArgs
  {
    TargetCriteria = searchCritCtl.CurrentCriteria.CriteriaId,
    SearchComparision = ParseCurrentComparer(searchCritCtl.scOperatorSelection.SelectedValue),
    SearchField = searchCritCtl.scFieldSelection.SelectedValue,
    SearchValue = searchCritCtl.scFilterValue.Text,
    ClickTarget = SearchCriteriaClickTarget.Update
  };
  if (ItemUpdated != null)
    ItemUpdated(this, scEArgs);
}

Страница рендеринга выбирает объекты данных из серверной части хранилища и отображает их в своем событии Page_Load. В этот момент все становится сложнее: я подключаюсь к пользовательским событиям!

int idIt = 0;
foreach (var item in _currentSearch.Items)
{
  SearchCriteria sc = (SearchCriteria)LoadControl("~/content/controls/SearchCriteria.ascx");
  sc.ID = "scDispCtl_" + idIt;
  sc.ControlMode = SearchCriteriaMode.Display;
  sc.CurrentCriteria = item;
  sc.ItemUpdated += CriteriaUpdated;
  sc.ItemRemoved += CriteriaRemoved;
  pnlDisplayCrit.Controls.Add(sc);
  idIt++;
}

При первом рендеринге страницы все отображается нормально, я получаю все свои данные. Когда я запускаю событие обновления, событие пользовательского элемента управления запускается корректно, но все поля и элементы управления пользовательского элемента управления NULL . После небольшого исследования мне пришлось прийти к выводу, что событие запускается до инициализации элементов управления ...

Есть ли способ предотвратить такое поведение / как-то переопределить жизненный цикл страницы? Я не могу инициализировать пользовательские элементы управления в Init-событии страницы, потому что мне нужно получить доступ к Session-Store (не инициализирован в Page_Init).

Любой совет приветствуется ...

EDIT:

Поскольку мы храним всю информацию о критериях в бэкэнде хранилища (включая количество критериев) и это хранилище использует идентификатор пользователя из сеанса, мы не можем использовать Page_Init ... только для пояснения

РЕДАКТИРОВАТЬ # 2:

Мне удалось преодолеть некоторые проблемы. Поскольку сейчас я использую простые типы, я могу декларативно связать все данные (используя повторитель с простым ItemTemplate). Это связано с контролем, они отображаются правильно. При обратной передаче все данные возвращаются в пользовательский элемент управления, данные доступны в событиях OnDataBinding и OnLoad, все выглядит хорошо.

Но как только оно входит в реальное событие (привязанное к кнопке управления пользовательского элемента управления), все значения полей как-то теряются ...

Кто-нибудь знает, как жизненный цикл страницы продолжает обрабатывать запрос после привязки / загрузки данных? Я схожу с ума по этому вопросу ...

Ответы [ 2 ]

0 голосов
/ 15 декабря 2009

Я разобрался с решением;)

Если я работаю с событием OnCommand на кнопках внутри usercontrol, я могу передать CommandArgument. Теперь я связываю идентификатор коллекции с параметром CommandArgument кнопки, которая позволяет мне обрабатывать все обратные передачи внутри usercontrol.

<asp:Button ID="scUpdate"
     runat="server"
     Text="Update"
     OnCommand="HandleCommand"
     CommandName="update"
     CommandArgument='<%# CriteriaId %>' />

Это объявление сохраняет CriteriaId (Guid) во всех постбэках и позволяет мне идентифицировать измененную запись в базовой коллекции (управляется на странице). В следующем фрагменте кода показано, как инициируется событие на странице подписки.

scEArgs = new SearchCriteriaEventArgs
          {
                TargetCriteria = new Guid(e.CommandArgument.ToString()),
                SearchComparision = ParseCurrentComparer(),
                SearchField = scFieldSelection.SelectedValue,
                SearchValue = scFilterValue.Text,
                ClickTarget = SearchCriteriaClickTarget.Update
          };

if (ItemUpdated != null)
  ItemUpdated(this, scEArgs);

Может быть, этот ответ кому-нибудь поможет, поэтому я просто опубликую его;)

0 голосов
/ 14 декабря 2009

Динамическое управление может быть кошмаром. Хитрость заключается в том, чтобы убедиться, что вы перепривязали все на обратной передаче.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...