首页 > 解决方案 > C#订阅和取消订阅事件 - 从“字符串”

问题描述

是否可以进行此更改,以避免重复代码过多?

如何改变这个:

protected string Write_TextBox1(string Text)
{
    TextBox1.TextChanged -= TextBox1_TextChanged;
    string text = string.Empty();
    TextBox1.Text = text;
    TextBox1.TextChanged += TextBox1_TextChanged;
    return text;
}

protected string Write_TextBox2(string Text)
{
    TextBox2.TextChanged -= TextBox2_TextChanged;
    string text = string.Empty();
    TextBox2.Text = text;
    TextBox2.TextChanged += TextBox2_TextChanged;
    return text;
}

像这样:

protected string Write_TextBox(TextBox tb, string Text)
{
    tb.TextChanged -= tb.ID + "_TextChanged";
    string text = string.Empty();
    tb.Text = text;
    tb.TextChanged += tb.ID + "_TextChanged";
    return text;
}

标签: c#

解决方案


从技术上讲,您可以尝试使用Reflection,例如

using System.Reflection;

...

protected string Write_TextBox(TextBox tb, string text) {
  if (null == tb)
    throw new ArgumentNullException(nameof(tb));

  var method = GetType().GetMethod(
    $"{tb.Name}_TextChanged", 
       BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

  if (null == method) {
    tb.Text = text ?? "";

    return text;
  }

  Delegate dlg = Delegate.CreateDelegate(typeof(EventHandler), this, method);

  // tb.TextChanged -= tb.ID + "_TextChanged";
  tb.GetType().GetEvent("TextChanged").RemoveEventHandler(tb, dlg);

  try {
    tb.Text = text ?? "";
  }
  finally {
    // tb.TextChanged += tb.ID + "_TextChanged";
    tb.GetType().GetEvent("TextChanged").AddEventHandler(tb, dlg); 
  }    

  return text;
}

然而,这是一个糟糕的设计(要求事件处理程序必须具有特殊名称的脆弱代码)。尝试为所有事件创建一个事件处理程序:TextChanged

  protected string Write_TextBox(TextBox tb, string text) {
    if (null == tb)
      throw new ArgumentNullException(nameof(tb));

    tb.TextChanged -= my_TextChanged;

    try {
      tb.Text = text ?? ""; 
    }
    finally {
      tb.TextChanged += my_TextChanged;
    } 

    return text; 
  }

在哪里

  public void my_TextChanged(object sender, EventArgs e) {
    // tb - TextBox that changed its Text
    TextBox tb = sender as TextBox;

    ...
  }

推荐阅读