views:

131

answers:

5

I have a USerControll in which i have a textbox. I use the usercontrol in my form, I want to do something when somebody presses enter on the textbox. how can I do it? if you tell me how to call an event manually, I can call usercontrol.keydown in textbox.keydown.

+3  A: 

First, events can only be raised from code within the control that declares the event. So, your user control has to declare the custom event KeyDown in order to raise it. You cannot, for instance, raise KeyDown on a TextBox contained by your user control. However, you can declare your own KeyDown, and attach a handler to the TextBox's KeyDown that will raise your own KeyDown.

Given this restriction, raising an event is easy:

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

Raising an event looks much like a method, because in essence that's what you're doing; you're calling one or more method delegates that are assigned to the MultiCast delegate behind the scenes of your event. Think of it as assigning a method to an ordinary named delegate (like if you'd omitted the "event" keyword from the definition) and calling it from inside your code. the only difference between a true event and that is that an event can have more than one handler delegate attached to it, and will invoke all of them when raised.

KeithS
Unfortunately, this code isn’t thread safe. You need to create a local copy of `MyEvent` to save-guard against `NullReferenceExceptions` arising when another thread concurrently removes all event handlers between your `if` and the event invocation.
Konrad Rudolph
... Or lock(MyEvent()) before evaluating the if, and releasing it afterward. The question was simply about raising an event and that's what I answered; if he's attaching and detaching handlers willy-nilly, that indicates a more advanced knowledge of events in general, precluding the need to ask the question.
KeithS
@KeithS: You’re right in principle but that’s not what I mean: copying the event locally is a firmly established best-practice. *No* event raising code should ever be written without it, not even as an example (since if you don’t expect the multithreading issue, you won’t think of it). Attaching events nilly-willy isn’t something the user control’s code can control – it’s up to the user. As a reusable code, the user control code should be as robust as possible.
Konrad Rudolph
Hmya, this is dogma but hardly relevant here. A control has only 4 members that are documented to be usable from another thread (InvokeRequired etc). Even MSFT doesn't do this consistently, NumericUpDown for example.
Hans Passant
A: 

What you describe is called event bubbling. Here's an example:

<%@ 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
 }
}
Nathan Taylor
Just to clarify as I may have misunderstood the question. Are you looking for 'Enter' specifically or are you trying to capture a submit via the TextBox?
Nathan Taylor
A: 

Typically, the event invokation is wrapped in a method named something like "On[EventName]" which validates that the delgate has one or more targets (event is not null), and then invokes it with the sender and any applicable arguments...so something like this is the typical pattern:

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

Anything that needs to raise that event invokes that method (assuming its accessible).

If you simply want to pass the event along, then as a UserControl, you can probably just invoke the base "On[Event]" method, which is likely exposed. You can wire up the event handlers, too, to directly pass the event from a child control as the event of the parent control...so that txtFoo.KeyPress simply invokes the OnKeyPress method of the parent control.

Steven
A: 

If you are using WPF, you might be able to use RaiseEvent: http://msdn.microsoft.com/en-us/library/system.windows.uielement.raiseevent.aspx

But this is wrong for what you want to do.

You should bubble the event.

class MyControl : UserControl {
    public KeyDownEventHandler KeyDown;

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

Then listen to KeyDown from your form. Please excuse mistakes in the naming of the various elements / events.

Krisc
A: 

I was looking for an answer to this issue for me,

just do this

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 }

I hope this was useful for you.

HoNgOuRu