Как через рефлексию получить все обработчики события? Ведь, когда я добавляю обработчик, он должен сохраняться в какое-то приватное поле.
Класс для получения списка делегатов для обычных классов (не наследников от класса Component
using System;
using System.Linq;
using System.Reflection;
namespace WindowsFormsApp1
{
public static class ReflectionHelper
{
public static Delegate[] GetSubscribedMethods(object instance, string eventName)
{
var type = instance.GetType();
var currentEvent = type.GetEvents().FirstOrDefault(ev => ev.Name == eventName);
if (currentEvent != null)
{
var eventFieldInfo = type.GetField(eventName,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField);
if (eventFieldInfo != null)
{
var eventFieldValue = (Delegate)eventFieldInfo.GetValue(instance);
return eventFieldValue.GetInvocationList();
}
}
return new Delegate[0];
}
}
}
И код с демонстрацией работы
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class MainForm : Form
{
private readonly Worker _worker;
public MainForm()
{
InitializeComponent();
Load += OnMainFormLoad;
_worker = new Worker();
_worker.SomeEvent1 += OnWorkerSomeEvent11;
_worker.SomeEvent1 += OnWorkerSomeEvent12;
_worker.SomeEvent2 += OnWorkerSomeEvent22;
}
private void OnWorkerSomeEvent11(object sender, EventArgs e)
{
}
private void OnWorkerSomeEvent12(object sender, EventArgs e)
{
}
private void OnWorkerSomeEvent22(object sender, EventArgs e)
{
}
private void OnMainFormLoad(object sender, EventArgs e)
{
var clickEventHandlers = ReflectionHelper.GetSubscribedMethods(
_worker, nameof(Worker.SomeEvent1));
var lostFocusEventHandlers = ReflectionHelper.GetSubscribedMethods(
_worker, nameof(Worker.SomeEvent2));
}
}
public class Worker
{
public event EventHandler SomeEvent1;
public event EventHandler SomeEvent2;
public void DoWork()
{
SomeEvent1?.Invoke(this, EventArgs.Empty);
SomeEvent2?.Invoke(this, EventArgs.Empty);
}
}
}
На примере Windows Forms
приложения и кнопки
using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
Load += OnMainFormLoad;
execButton.Click += OnButtonClick1;
execButton.Click += OnButtonClick2;
execButton.LostFocus += OButtonLostFocus;
}
private static Delegate[] GetInvocationListOfEvent(Control control, string eventName)
{
FieldInfo fieldInfo = typeof(Control).GetField(
"Event" + eventName, BindingFlags.Static | BindingFlags.NonPublic);
if (fieldInfo != null)
{
PropertyInfo pi = control.GetType().GetProperty("Events",
BindingFlags.NonPublic | BindingFlags.Instance);
if (pi != null)
{
var list = (EventHandlerList)pi.GetValue(control, null);
object obj = fieldInfo.GetValue(control);
return list[obj].GetInvocationList();
}
}
return new Delegate[0];
}
private void OnMainFormLoad(object sender, EventArgs e)
{
var clickEventHandlers = GetInvocationListOfEvent(
execButton, nameof(Control.Click));
var lostFocusEventHandlers = GetInvocationListOfEvent(
execButton, nameof(Control.LostFocus));
}
private void OButtonLostFocus(object sender, EventArgs e)
{
}
private void OnButtonClick1(object sender, EventArgs e)
{
}
private void OnButtonClick2(object sender, EventArgs e)
{
}
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
как показать отсчет времени при запуске/перезапуске сцены?
Проект ASPNET Core WebAPI, ORM EF Core, база данных MySQL, провайдер Pomelo
Сначала я отключаю просмотр всех скрытых файлов и папок через реестр: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
Имеется код который запускает label и он движется ровно от середины до края