對某個控制項的事件進行編程;如,需要將當前運行期的按鈕替換掉,並且保留它的原始事件引用;方法如下:
測試代碼
看不到圖的請直接copy code
代碼
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("click by " + ((Button)sender).Name);
}
public void button2_Click(object sender, EventArgs e)
{
//調用button1 的click事件,並傳遞參數
CalleventRaiseEvent(button1, "Click", button1, null);
}
private void button3_Click(object sender, EventArgs e)
{
//構造個新的按鈕
var btn3 = new Button { Name = "btnTest_createNew", Text = "新按鈕", Parent = this,
Left = button1.Left + button1.Width + 10, Top = button1.Top, Visible = true };
//btn3.Click += (s, a) => CalleventRaiseEvent(button1, "Click", button1, null);
//將舊按鈕事件放到新按鈕上去
ReplaceEvent(button1, btn3, "Click");
//刪除舊按鈕
button1.Dispose();
button1 = null;
}
/// <summary>
/// 替換事件到控制項
/// 必須保證 EventHandler 類型一致,否則會失敗
/// </summary>
/// <param name="sourceControl">原控制項</param>
/// <param name="destControl">目標控制項</param>
/// <param name="eventName">事件明</param>
public void ReplaceEvent(Control sourceControl, Control destControl, string eventName)
{
if (sourceControl == null || destControl == null || string.IsNullOrEmpty(eventName))
throw new NullReferenceException();
Type type = sourceControl.GetType();
PropertyInfo propertyInfo = type.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
var eventHandlerList = (EventHandlerList)propertyInfo.GetValue(sourceControl, null);
FieldInfo fieldInfo = (typeof(Control)).GetField("Event" + eventName, BindingFlags.Static | BindingFlags.NonPublic);
Delegate d = eventHandlerList[fieldInfo.GetValue(null)];
if (d != null)
{
foreach (Delegate di in d.GetInvocationList())
destControl.GetType().GetEvent(eventName).AddEventHandler(destControl, d);
}
else
throw new InvalidCastException("無效的事件轉換!");
}
/// <summary>
/// 呼叫事件方法
/// </summary>
/// <param name="control">目標控制項</param>
/// <param name="eventName">方法名</param>
/// <param name="args">方法參數</param>
public void CalleventRaiseEvent(Control control, string eventName, params object[] args)
{
if (control == null || string.IsNullOrEmpty(eventName))
throw new NullReferenceException();
Type type = control.GetType();
EventInfo eventInfo = type.GetEvent(eventName);
MethodInfo methodInfo = eventInfo.GetRaiseMethod();
if (methodInfo != null)
methodInfo.Invoke(this, args);
else
{
PropertyInfo propertyInfo = type.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
var eventHandlerList = (EventHandlerList)propertyInfo.GetValue(control, null);
FieldInfo fieldInfo = (typeof(Control)).GetField("Event" + eventName, BindingFlags.Static | BindingFlags.NonPublic);
Delegate d = eventHandlerList[fieldInfo.GetValue(null)];
if (d != null)
{
foreach (Delegate di in d.GetInvocationList())
di.DynamicInvoke(args);
}
else
throw new NullReferenceException("無效的事件激發!");
}
}