2011-10-04 12 views
5

Estoy desconcertando sobre un problema de plomería de eventos en mi página. Tengo un solo UserControl de ASP.NET que supervisa algunos eventos del lado del navegador y los plantea como UpdatePanel async-back-backs en el servidor. Vamos a llamarlo EventPump. Incluye algunos controles JavaScript y del lado del servidor para administrar los eventos. Funciona muy bien.¿Múltiples suscriptores al evento UserControl de ASP.NET único?

Tengo otros controles en la misma página que no se conocen entre sí, pero me gustaría suscribirme a algunos de los eventos planteados por EventPump. Normalmente, un control se suscribiría a los eventos de otro al incluir ese control en su marcado y cablear los eventos. Pero en este caso eso me daría varias instancias de EventPump, que no quiero.

¿Cómo puedo tener varios UserControls suscritos a eventos del control común EventPump?

Respuesta

1

Unas pocas opciones adicionales que se me ocurren:

  1. Código a las interfaces, por lo que el control de EventPump implementa IEventPump que tiene un varios eventos públicos.La página que implementa IEventPumpContainer con una propiedad llamada EventPump que permite a todos los otros controles de usuario que se registre como tal:

    ((IEventPumpContainer)Page).EventPump.MyEvent += MyEventHandler; 
    
  2. Si el página es consciente de los controles que deba suscribirse usted podría tener que llamar a métodos apropiados en los controles cuando los eventos se disparan. Por ejemplo:

    EventPump.MyEvent += (s, e) => SomeControl.SomeMethod(); 
    
  3. alternativa y posiblemente mejor es hacer que los eventos ciudadanos de primera clase y tienen un despachador de eventos que se pueden utilizar para suscribirse y provocar eventos. Por ejemplo:

    Events.Register<MyEvent>(e => TextBox.Text = "MyEvent Happened"); 
    ... 
    Events.Raise(new MyEvent()); 
    
0

Crear controladores de eventos en los controles de usuario y suscribir todos los eventos al mismo controlador en la página.

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); 
}  

Página:

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

de código subyacente:

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

EDITAR

Consulte este artículo para invocar eventos a través de los controles de usuario:

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

+1

Creo que tienes esto al revés. El problema es que múltiples controles de usuario quieren suscribirse a eventos en otro control de usuario, pero no tienen acceso a este último control directamente. –

0

un par de opciones:

  1. Coloque el EventPump en una página maestra y crear una propiedad que lo hace referencia (haciendo que la página maestra sea "fuertemente tipada" mediante la directiva @MasterType)

  2. Agregue un método de ayuda estático que tome una instancia de página como parámetro y encuentre la instancia de EventPump en la página. En lugar de usar FindControl para esto, que será lento en páginas grandes, simplemente puede registrar el control en Page.Items. Este enfoque se combina mejor con el código en el control EventPump que garantiza que solo exista una instancia EventPump en la página.

  3. Realice un control EventPumpProxy al estilo de ScriptManagerProxy. Esto es un poco complicado, pero es bueno si prefiere tener un marcado declarativo localmente en lugar de muchos códigos subyacentes. No sé los detalles exactos de la implementación, pero debería poder verlos desensamblando las fuentes del marco AJAX.

Cuestiones relacionadas