0

我正在尝试为 RichTextBox (RTB) 创建扩展方法 Clone()。

我想将新 RTB 的 TextChanged 事件处理程序设置为旧 RTB 的 TextChanged 事件处理程序。例如:

newRTB.TextChanged += oldRTB.TextChanged;

但是,会出现以下错误:

“事件 'System.Windows.Forms.Control.TextChanged' 只能出现在 += 或 -= 的左侧。”

一种可能的解决方案是将事件处理程序作为参数添加到克隆方法并重新创建事件,但我需要为多个事件执行此操作,这会变得很麻烦。有任何想法吗?

“=”符号似乎也不起作用。

4

3 回答 3

1

我们可以通过复制事件reflection。现在我自己会对此保持警惕,所以请彻底测试所有版本(2.0、3.0、4.0)。我尝试了很多方法,但以下是唯一的方法,我让它工作。在 .NET 4.0 上运行了冒烟测试。

在表单类上创建扩展方法

public static class FormExtension
{
   public static void CopyEvent(this Form form, Control src, string fieldName, string eventName, Control dest)
   {
       EventHandlerList events = (EventHandlerList)typeof(Control)
                                  .GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance)
                                  .GetValue(src, null);
       object key = typeof(Control).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
       EventInfo evInfo = typeof(Control).GetEvent(eventName, BindingFlags.Public | BindingFlags.Instance);
       Delegate del = events[key];
       if (del != null)
       {
           Delegate d = Delegate.CreateDelegate(evInfo.EventHandlerType, form, del.Method);
           MethodInfo addHandler = evInfo.GetAddMethod();
           Object[] addHandlerArgs = { d };
           addHandler.Invoke(dest, addHandlerArgs);
       }
   }
}

现在像这样使用它

这里我展示了一个复制clicktext changed事件的例子。

this.CopyEvent(richTextBox1, "EventText", "TextChanged", richTextBox2);
this.CopyEvent(richTextBox1, "EventClick", "Click", richTextBox2);

如何将其用于其他活动

您必须Control通过 Reflector 打开课程并获取fieldeventnames.

所以在这种情况下Text Changed是这样的:

public event EventHandler TextChanged    <-----The Event name for the "CopyEvent" function
{
    add
    {
        base.Events.AddHandler(EventText, value);
    }
    remove
    {
        base.Events.RemoveHandler(EventText, value);
    }
}

EventText在哪里

private static readonly object EventText = new object();  <-------The Field name
于 2014-03-29T07:54:11.793 回答
0

如果您预先创建了 TextChanged 事件,您可以这样做,在一个表单中放置两个 TextBox 和一个 Button,这将使您的控件共享该事件。

private void button1_Click(object sender, EventArgs e)
{
    textBox2.TextChanged += new EventHandler(textbox1_TextChanged);
}

private void textbox1_TextChanged(object sender, EventArgs e)
{
    MessageBox.Show("this");
}

更新

在另一个文件中,创建你想要的方法,你可以把当前事件的代码复制到这个方法中,然后你只需将它分配给新的控件

void MyCloned_TextChanged(object sender, EventArgs e)
{ 
    // Shared method OldRTB to share with NewRTB

}

在表格中,您将像这样使用它

public Form1()
{
    InitializeComponent();

    textBox1.TextChanged += new EventHandler(MyCloned_TextChanged);
    textBox2.TextChanged += new EventHandler(MyCloned_TextChanged);
}
于 2014-03-29T03:37:09.753 回答
0

尝试这个:

newRTB.TextChanged  += new TextChangedEventHandler(oldRTB_textChanged);

创建一个这样的方法:

void oldRTB_textChanged(object sender, EventArgs e)
{
   // do something
}
于 2014-03-29T03:39:02.973 回答