ASP.net динамически создаваемая обработка событий управления - PullRequest
1 голос
/ 18 июля 2009

По существу, у меня динамически добавляется заполнитель на странице при загрузке страницы.

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

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

MyControl.Create(args, new EventHandler(OnClick)); 

Тогда на странице у меня будет protected void OnClick(object o, EventArgs args) {}

Конечно, когда я звоню create(), я подключаю свой обработчик событий к событию нажатия кнопки составного элемента управления. Все идет нормально. Когда кнопка подключена, нажатие кнопки возвращает сообщения в элемент управления, как и ожидалось. Однако событие никогда не возвращается обратно в обработчик событий страницы.

Я понимаю, что проблема возникает при обратной передаче. Тем не менее, попытка связать кнопку на init, load или createchildcontrols не в состоянии удержать проводку на месте, чтобы событие могло быть обработано на странице. Что мне хотелось бы, так это возможность передавать обработчик событий в составной элемент управления во время выполнения и для составного элемента управления правильно отправлять событие обратно на страницу при обратной передаче.

Интересно, что если я вызываю OnBubble с пользовательскими событиями, я могу поймать всплывающее событие на странице. Но проблема в том, что мой заполнитель находится на странице, поэтому, когда я пытаюсь вызвать, например, MyControl.Create() в UserControl, пузырь переходит на страницу, а не в UserControl (как и ожидалось). Следовательно, причина, по которой я предпочитаю объявлять обработчик событий вместо переопределения OnBubble (UserControls и другие элементы управления, которые объявляют MyControl, по существу сделали бы его бесполезным для событий нажатия кнопки).

Я надеюсь, что у кого-то есть понимание этой проблемы. Это кажется интересной проблемой, но, возможно, нет другого решения, кроме как объявить элемент управления на странице и напрямую связать событие в разметке или при загрузке страницы. Я хотел бы рассмотреть возможность выполнения кнопки асинхронного обратного вызова, но предпочел бы использовать стандартную обработку событий ASP.NET, если это возможно.

Спасибо!

Чтобы добавить пояснения: вызов MyControl.Create() фактически генерирует событие, которое вызывает метод Create() Composite Control. это все хорошо, но стоит отметить, что метод MyControl.Create() не имеет прямого доступа к элементу управления. Это должно иметь смысл, поскольку элемент управления добавляется на страницу onload, которая не находится в разметке.

Подробнее код:

MyControl : CompositeControl 
{
     public event EventHandler Click;

     //I have a create method
     void Create(args, EventHandler click)
     {
          this.Click = click;
          //other processing
     }

     //then the button is wired up. I've tried in OnInit(), OnLoad()
     void CreateChildControls()
     {
           MyButton.OnClick += Click;
     }

     //if I wire up the button to a default handler I can check if
       Click is not null and send the click event onto the next handler 
     //this is where the bubble event works, but the wiring fails
} 

Редактировать: Моя попытка сохранить обработчик событий в сеансе и подключить кнопку при обратной передаче была успешной. Я не считаю это хорошей практикой, и я не думаю, что она на самом деле служит моей цели. Например, в этом случае событие на странице выполняется должным образом, но с нестандартным поведением страницы. Например, Response.Redirect () генерирует исключение. Это должно иметь смысл, потому что обработчик событий, вероятно, потерял информацию о состоянии во время обратной передачи. Пара мыслей: 1. Возможно ли, что я мог создать собственное событие пузыря, которое каким-то образом связано с этим элементом управления? Это кажется правдоподобным, но опять же проблема обратной передачи страницы оставляет меня с той же проблемой, где пузырь должен идти. Итак, когда я вызываю create (), возможно ли, что я могу автоматически зарегистрировать UserControl в качестве места назначения для пузыря? Это кажется сложным.2. Есть ли в жизненном цикле страницы какой-то момент, когда я могу повторно подключить событие к объявленному обработчику событий UserControl, чтобы делегат вызывался правильно при обратной передаче? Кажется, это то, чего мне не хватает. Обработчик событий создается при обратной передаче, но теряется, потому что он не создается заново в UserControl во время OnClick. Я не хочу, чтобы UserControl должен был явно воссоздавать эту вещь, но хочу, чтобы дочерний элемент управления создал ее заново для UserControl. Это звучит как простой запрос, но с UserControl вне цикла, я могу просить невозможного.

Ответы [ 4 ]

1 голос
/ 19 июля 2009

Вы не упомянули конкретно, в какой точке жизненного цикла страницы вы создаете и добавляете эти элементы управления. Для обратной передачи все создание (и подключение) и повторное создание должны быть выполнены до события page_load.

Сделайте это в page_init, и механизм viewstate должен принять значения обратной передачи, если идентификаторы совпадают.

Я наткнулся здесь на другой метод: http://www.codeproject.com/KB/viewstate/retainingstate.aspx

0 голосов
/ 27 мая 2010

Вы всегда должны ставить один и тот же идентификатор для динамически создаваемых элементов управления, если вы не выполняете его, иногда события элемента управления не генерируются,

надеюсь, что это поможет.

0 голосов
/ 19 июля 2009

Хорошо, поправьте меня, если я ошибаюсь, ваш метод Create () фактически создает и устанавливает ваш внутренний контроль в известное состояние; Я вижу, что у вас уже есть ссылка на кнопку, тогда зачем вам в этот момент дополнительное событие Click?

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

MyControl : CompositeControl
{
    void Create(args, EventHandler click)
    {
        // init & set up your control

        // other processing

        MyButton.OnClick += click;
    }
}
0 голосов
/ 18 июля 2009

Какова ваша мотивация для динамического добавления элемента управления в заполнитель? Страница на самом деле не существует между запросами, поэтому любые элементы управления, которые вставляются динамически, не сохраняются. Тебе, по сути, придётся подделать это.

Одним из вариантов, который вы можете рассмотреть, является написание пользовательского элемента управления, который имеет разные режимы рендеринга, но имеет согласованный интерфейс событий. Другой способ - использовать элемент управления ASP.NET MultiView, который будет отображать только видимое представление в HTML, но при этом поддерживать обработчики событий в невидимых представлениях.

...