2010-10-01 57 views
8

Tengo un USerControll en el que tengo un cuadro de texto. Utilizo usercontrol en mi forma, quiero hacer algo cuando alguien presiona enter en el cuadro de texto. ¿Cómo puedo hacerlo? si me dices cómo llamar a un evento de forma manual, puedo llamar a usercontrol.keydown en textbox.keydown.¿Cómo llamar un evento manualmente en C#?

+0

Por lo tanto, desea plantear el evento UserControl.KeyDown desde el controlador de eventos TextBox.KeyDown, ¿verdad? – dtb

+0

Entonces, ¿responder al evento cuando el usuario realmente presiona una tecla no es suficiente para su escenario? Creo que me falta algo en tu escenario. – RQDQ

+0

@dtb: sí, solo a la derecha – Saeed

Respuesta

10

En primer lugar, los eventos solo se pueden generar desde el código dentro del control que declara el evento. Por lo tanto, su control de usuario debe declarar el evento personalizado KeyDown para poder generarlo. No puede, por ejemplo, subir KeyDown en un TextBox contenido por su control de usuario. Sin embargo, puede declarar su propio KeyDown y adjuntar un controlador al KeyDown de TextBox que elevará su KeyDown.

Teniendo en cuenta esta restricción, se provoca un evento es fácil:

public delegate void MyEventHandler(object sender, MyEventArgs e) 

public event MyEventHandler MyEvent; 

public void RaisesMyEvent() 
{ 
    ... 

    if(MyEvent != null) //required in C# to ensure a handler is attached 
     MyEvent(this, new MyEventArgs(/*any info you want handlers to have*/)); 
} 

provoca un evento, parece mucho a un método, porque en esencia eso es lo que está haciendo; está llamando a uno o más delegados de métodos que están asignados al delegado de MultiCast detrás de las escenas de su evento. Piense en ello como asignar un método a un delegado con nombre común (como si hubiera omitido la palabra clave "evento" de la definición) y llamarlo desde dentro de su código. la única diferencia entre un evento verdadero y ese es que un evento puede tener más de un delegado controlador asociado, e invocará a todos ellos cuando se lo plantee.

+0

Desafortunadamente, este código no es seguro para subprocesos. Necesita crear una copia local de 'MyEvent' para guardar-guardar contra' NullReferenceExceptions' que surge cuando otro hilo al mismo tiempo elimina todos los controladores de eventos entre su 'if' y la invocación de evento. –

+0

... O bloquear (MyEvent()) antes de evaluar el if y soltarlo después. La pregunta era simplemente acerca de plantear un evento y eso es lo que respondí; si está conectando y separando manejadores de cualquier manera, eso indica un conocimiento más avanzado de los eventos en general, lo que excluye la necesidad de hacer la pregunta. – KeithS

+0

Tienes razón en principio, pero eso no es lo que quiero decir: copiar el evento localmente es una mejor práctica firmemente establecida. * Ningún código de generación de eventos debe escribirse sin él, ni siquiera como ejemplo (ya que si no espera el problema de subprocesamiento múltiple, no lo pensará). Adjuntar eventos de cualquier manera no es algo que el código de control del usuario pueda controlar: depende del usuario. Como código reutilizable, el código de control del usuario debe ser lo más robusto posible. –

0

Lo que describes se llama evento de burbujeo. He aquí un ejemplo:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyUserControl.ascx.cs" Inherits="MyUserControl" %> 

<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged" /> 

public partial class MyUserControl : UserControl 
{ 
public event EventHandler UserControlTextBoxChanged; 

protected void TextBox1_TextChanged(object sender, EventArgs e) { 
    if (UserControlTextBoxChanged != null) 
    UserControlTextBoxChanged(sender, e); 
} 
} 

<%@ Page Language="C#" AutoEventWireup="True" Inherits="Default" CodeBehind="Default.aspx.cs" %> 
<%@ Register Src="~/MyUserControl.ascx" TagName="MyUserControl" TagPrefix="uc1" %> 

<uc1:MyUserControl ID="ucMyUserControl" runat="server" OnUserControlTextBoxChanged="ucMyUserControl_UserControlTextBoxChanged" /> 

public partial class MyPage : Page { 
protected void ucMyUserControl_UserControlTextBoxChanged(object sender, EventArgs e) { 
    // sender is ucMyUserControl.TextBox1 
} 
} 
+0

Solo para aclarar, ya que pude haber malentendido la pregunta. ¿Está buscando 'Enter' específicamente o está tratando de capturar un envío a través del TextBox? –

1

Típicamente, la invocación caso se envuelve en un método llamado algo así como "El [eventName]" que valida que el delgate tiene uno o más objetivos (el evento no es nulo), y luego lo invoca con el remitente y cualquier argumentos aplicables ... así que algo como esto es el patrón típico:

public event EventHandler SomethingHappened; 
protected void OnSomethingHappend(EventArgs e) 
{ 
    if (SomethingHappened != null) 
     SomethingHappened(this, e); 
} 

Todo lo que necesita para levantar ese evento, se invoca este método (asumiendo su accesible).

Si simplemente desea pasar el evento, entonces como UserControl, probablemente solo pueda invocar el método base "On [Event]", que probablemente esté expuesto. También puede conectar los manejadores de eventos para pasar directamente el evento desde un control secundario como el evento del control principal ... de modo que txtFoo.KeyPress simplemente invoque el método OnKeyPress del control principal.

0

Si está utilizando WPF, es posible que pueda utilizar RaiseEvent: http://msdn.microsoft.com/en-us/library/system.windows.uielement.raiseevent.aspx

Pero esto está mal para lo que quiere hacer.

Debería hacer burbujear el evento.

class MyControl : UserControl { 
    public KeyDownEventHandler KeyDown; 

    private void OnTextBoxKeyDown(object sender, EventArgs e){ KeyDown.Invoke(sender, e); } 
} 

Luego escuche KeyDown en su formulario. Disculpe los errores en la denominación de los diversos elementos/eventos.

2

que estaba buscando una respuesta a este problema para mí,

a hacer esto

examble:

//this is the call to trigger the event: 

**lst_ListaDirectorios_SelectedIndexChanged(this, new EventArgs());** 

//do that if you have the method signature in the same class as I do. (something like this below) 
private void lst_ListaDirectorios_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      //do something 
     } 

Espero que esto era útil para usted.

Cuestiones relacionadas