J'ai un programme où je suis à l'aide de la Réflexion pour charger les classes de façon dynamique en fonction d'un fichier texte.
Lorsque j'exécute mon code je peux obtenir toutes les classes, méthodes et Événements de l'impression à l'écran et peut même Appeler les méthodes.
J'ai ajouté tous les événements d'un Dictionnaire et je tiens à les énumérer, puis créer un Gestionnaire d'Événements pour obtenir les données envoyées par l'événement.
voici ma méthode pour obtenir les événements d'un dictionnaire:
private Dictionary<string, EventInfo> RetrieveEvents(string label, string type)
{
try
{
this.displaysAssembly = Assembly.LoadFrom(Path.Combine(Directory.GetApplicationDirectory(), "Framework.DisplayDrivers.dll"));
string assembly = string.Format("Framework.DisplayDrivers.{0}", type);
Type cswitcher = displaysAssembly.GetType(assembly);
fullClass = cswitcher;
Dictionary<string, EventInfo> ekvp = new Dictionary<string, EventInfo>();
List<EventInfo> eventInfos = cswitcher.GetEvents().Where(e => HasInformationAttribute(e)).ToList();
foreach (var e in eventInfos)
{
if (!ekvp.ContainsKey(label))
{
ekvp.Add(e.Name, e);
}
}
return (ekvp);
}
catch (MissingMethodException e)
{
ErrorLog.Error(LogHeader + "Unable to create Display. No constructor: {0}", e.Message);
}
catch (ArgumentException e)
{
ErrorLog.Error(LogHeader + "Unable to create Display. No type: {0}", e.Message);
}
catch (NullReferenceException e)
{
ErrorLog.Error(LogHeader + "Unable to create Display. No match: {0}", e.Message);
}
return null;
}
si j'ai imprimer le Dictionnaire, je peux voir les événements par une Clé et une Valeur.
mais je n'arrive pas à créer un gestionnaire d'Événements. J'ai essayé de nombreuses options, y compris:
foreach(var evnt in d._projectors._events)
{
EventInfo ev = evnt.Value;
try
{
// this id not work
object classInstance = Activator.CreateInstance(d._projectors.fullClass);
ev.AddEventHandler(classInstance, new EventHandler(DisplayChangeEvents.DisplayMuteChangedEvent));
// this did not work either
if (d._projectors._events.TryGetValue("OnPowerStateRecieved", out ev))
{
ev.AddEventHandler(ev.Name, new EventHandler(DisplayChangeEvents.DisplayPowerChangedEvent));
}
}
catch (Exception ex)
{
ErrorLog.Error("Error creating event handers : " + ex.Message + "\r");
}
}
je suis en train de subscibe à l'événement et de manipuler les données dans une autre classe nommée "DisplayChangeEvents".
j'ai essayé pendant 2 jours pour arriver, et sa dernière pièce que j'ai besoin pour obtenir le programme fonctionne comme prévu.
Merci d'avance
basé sur une suggestion j'ai mis à jour le code dans la boucle foreach pour :
foreach(var evnt in d._projectors._events)
{
EventInfo ev = evnt.Value;
try
{
if (evnt.Key == "OnPowerStateRecieved")
{
ev.AddEventHandler(d._projectors.fullClass, new EventHandler(DisplayChangeEvents.DisplayPowerChangedEvent));
}
else if (evnt.Key == "OnMuteStateRecieved")
{
ev.AddEventHandler(d._projectors.fullClass, new EventHandler(DisplayChangeEvents.DisplayMuteChangedEvent));
}
// this id not work
// object classInstance = Activator.CreateInstance(d._projectors.fullClass);
// ev.AddEventHandler(classInstance, new EventHandler(DisplayChangeEvents.DisplayMuteChangedEvent));
//ev.AddEventHandler(d._projectors.fullClass, new EventHandler(DisplayChangeEvents.DisplayMuteChangedEvent));
//// this did not work either
//if (d._projectors._events.TryGetValue("OnPowerStateRecieved", out ev))
//{
// ev.AddEventHandler(ev.Name, new EventHandler(DisplayChangeEvents.DisplayPowerChangedEvent));
//}
}
obtenez de l'exception suivante:
Cast spécifié n'est pas valide.
la classe qui est la création d'événements ressemble à ceci:
private static event EventHandler<PowerStateEventsArgs> _onPowerStateRecieved = delegate { };
[Information(Description = "Power Event")]
public static event EventHandler<PowerStateEventsArgs> OnPowerStateRecieved
{
add
{
if (!_onPowerStateRecieved.GetInvocationList().Contains(value))
{
_onPowerStateRecieved += value;
}
}
remove
{
_onPowerStateRecieved -= value;
}
}
l'événement qui déclenche l'événement ressemble à ceci:
if (i == 1)
{
_onPowerStateRecieved(null, new PowerStateEventsArgs(true));
}
cette logique fonctionne dans tous les autres programmes, sauf quand je suis en train de réflexion afin de créer les classes dynamiquement.