Несколько подписчиков на одно событие ASP.NET UserControl? - PullRequest
5 голосов
/ 04 октября 2011

Я ломаю голову над проблемой сантехники на моей странице.У меня есть один ASP.NET UserControl, который отслеживает некоторые события на стороне браузера и вызывает их как UpdatePanel async-post-backs на сервер.Давайте назовем это EventPump.Он включает в себя некоторые JavaScript и серверные элементы управления для управления событиями.Это прекрасно работает.

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

Как можно, чтобы несколько пользовательских элементов управления подписывались на события общего элемента управления EventPump?

Ответы [ 3 ]

1 голос
/ 05 октября 2011

Несколько дополнительных опций, которые я могу придумать:

  1. Код для интерфейсов, поэтому элемент управления EventPump реализует IEventPump, который имеет различные открытые события. Содержащая страница реализует IEventPumpContainer с одним свойством EventPump, которое позволяет всем другим пользовательским элементам управления регистрироваться следующим образом:

    ((IEventPumpContainer)Page).EventPump.MyEvent += MyEventHandler;
    
  2. Если на странице известны элементы управления, на которые необходимо подписаться, вы можете вызвать соответствующие методы для элементов управления при возникновении событий. Например:

    EventPump.MyEvent += (s, e) => SomeControl.SomeMethod();
    
  3. В качестве альтернативы и, возможно, возможно, лучше сделать события первоклассными гражданами и иметь диспетчера событий, который можно использовать для подписки на события и их инициирования. Например:

    Events.Register<MyEvent>(e => TextBox.Text = "MyEvent Happened");
    ...
    Events.Raise(new MyEvent());
    
0 голосов
/ 04 октября 2011

Пара вариантов:

  1. Поместите EventPump на главную страницу и создайте свойство, которое ссылается на него (сделав главную страницу "строго типизированной" с помощью директивы @MasterType)

  2. Добавить статический вспомогательный метод, который принимает экземпляр страницы в качестве параметра и находит экземпляр EventPump на странице. Вместо того, чтобы использовать FindControl для этого, который будет медленным на больших страницах, вы можете просто зарегистрировать элемент управления в Page.Items. Этот подход лучше всего сочетается с кодом в элементе управления EventPump, который гарантирует, что на странице существует только один экземпляр EventPump.

  3. Создание элемента управления EventPumpProxy в стиле ScriptManagerProxy. Это несколько глупо, но хорошо, если вы предпочитаете иметь декларативную разметку локально, а не много кода. Я не знаю точных деталей реализации, но вы сможете увидеть их, разобрав исходные тексты AJAX-фреймворка.

0 голосов
/ 04 октября 2011

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

UserControl1:

public event EventHandler SomethingChanged;

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
    //do OnSelectedIndexChanged logic

    if (this.SomethingChanged != null)
        this.SomethingChanged(this, e);
}

protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
    //do OnCheckedChanged logic

    if (this.SomethingChanged != null)
        this.SomethingChanged(this, e);
}

UserControl2:

public event EventHandler SomethingElseChanged;

protected void TextBox1_TextChanged(object sender, EventArgs e)
{
    //do OnTextChanged logic

    if (this.SomethingElseChanged != null)
        this.SomethingElseChanged(this, e);
}

protected void Button1_Click(object sender, EventArgs e)
{
    //do OnClick logic

    if (this.SomethingElseChanged != null)
        this.SomethingElseChanged(this, e);
}    

Страница:

<uc:UserControl1 ID="UserControl1" runat="server" SomethingChanged="UserControl_Changed" ... />
<uc:UserControl2 ID="UserControl2" runat="server" SomethingElseChanged="UserControl_Changed" ... />

Код-за:

protected void UserControl_Changed(object sender, EventArgs e)
{
    Label1.Text = "Stuff has changed...";
}

EDIT

См. Эту статью для вызова событий через пользовательские элементы управления:

http://www.codeproject.com/KB/aspnet/EventsAcrossUCs.aspx

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