我有一个USerControll,我有一个文本框。我在表单中使用usercontrol,当有人在文本框中按Enter键时我想做某事。我该怎么做? 如果你告诉我如何手动调用事件,我可以在textbox.keydown中调用usercontrol.keydown。
答案 0 :(得分:12)
首先,只能从声明事件的控件中的代码引发事件。因此,您的用户控件必须声明自定义事件KeyDown才能引发它。例如,您不能在用户控件包含的TextBox上引发KeyDown。但是,您可以声明自己的KeyDown,并将一个处理程序附加到TextBox的KeyDown,它将引发您自己的KeyDown。
鉴于此限制,举办活动很容易:
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*/));
}
举起一个事件看起来很像一个方法,因为从本质上讲,这就是你正在做的事情;您正在调用在事件幕后分配给MultiCast委托的一个或多个方法委托。可以把它想象成为一个普通的命名委托分配一个方法(比如你从定义中省略了“event”关键字)并从你的代码中调用它。 true事件与事件之间的唯一区别是事件可以附加多个处理程序委托,并在引发时调用所有事件。
答案 1 :(得分:3)
我正在寻找这个问题的答案,
就这样做
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
}
我希望这对你有用。
答案 2 :(得分:1)
通常,事件调用包含在名为“On [EventName]”的方法中,该方法验证delgate是否有一个或多个目标(事件不为空),然后使用发送方和任何适用的参数调用它......所以像这样的典型模式:
public event EventHandler SomethingHappened;
protected void OnSomethingHappend(EventArgs e)
{
if (SomethingHappened != null)
SomethingHappened(this, e);
}
任何需要引发该事件的事件都会调用该方法(假设它是可访问的)。
如果你只想传递事件,那么作为UserControl,你可能只是调用可能暴露的基础“On [Event]”方法。您也可以连接事件处理程序,直接将子控件中的事件作为父控件的事件传递...以便txtFoo.KeyPress只调用父控件的OnKeyPress方法。
答案 3 :(得分:0)
您所描述的内容称为事件冒泡。这是一个例子:
<%@ 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
}
}
答案 4 :(得分:0)
如果您使用的是WPF,则可以使用RaiseEvent:http://msdn.microsoft.com/en-us/library/system.windows.uielement.raiseevent.aspx
但这对你想做的事情是错误的。
你应该为这个事件起泡。
class MyControl : UserControl {
public KeyDownEventHandler KeyDown;
private void OnTextBoxKeyDown(object sender, EventArgs e){ KeyDown.Invoke(sender, e); }
}
然后从表单中收听KeyDown。请原谅各种元素/事件的命名错误。
答案 5 :(得分:-1)
如果您真的需要手动调用事件,则可以获取通常是私有的后备委托。使用.NET反编译器(例如ILSPY)找到事件的后备字段,然后使用反射来获取后备委托。
示例:从DoWork
获取事件BackgroundWorker
:
在ILSpy中反编译BackgroundWorker
类,您会看到以下内容:
public event DoWorkEventHandler DoWork
{
add
{
base.Events.AddHandler(doWorkKey, value);
}
remove
{
base.Events.RemoveHandler(doWorkKey, value);
}
}
因此,您需要找到Events
成员,并将doWorkKey
字段作为键。
Events
是在类EventHandlerList
中声明的Component
(公共类)。
doWorkKey
是在类BackgroundWorker
中声明的静态字段。
然后使用反射来获取委托:
PropertyInfo property = backgroundWorker.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
EventHandlerList eventHandlerList = (EventHandlerList)property.GetValue(backgroundWorker, null);
FieldInfo doWorkField = backgroundWorker.GetType().GetField("doWorkKey", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy);
object doWorkKey = doWorkField.GetValue(null);
DoWorkEventHandler doWork = (DoWorkEventHandler)eventHandlerList[doWorkKey];
现在您有一个DoWork
事件的委托人,可以调用它。
同样的方法也适用于其他控件。
请注意,只要有新版本的代码,使用反射来获取私有字段可能会中断。