private unsafe bool TrySetEventReflection (XamlCallbackData *data, string xmlns, object publisher, string type_name, string name, Value* value_ptr, out string error)
{
object subscriber = null;
EventInfo ie = publisher.GetType ().GetEvent (name);
string handler_name = Value.ToObject (null, value_ptr) as string;
try {
subscriber = Value.ToObject (null, data->top_level);
} catch {
}
//Console.WriteLine ("TrySetEventReflection ({0}, {1}, {2}, {3}, {4}, {5}) handler_name: {6}", data->top_level, xmlns, publisher, type_name, name, value_ptr, handler_name);
if (ie == null) {
error = "Event does not exist.";
return false;
}
if (handler_name == null) {
error = "No method name supplied for event handler.";
return false;
}
MethodInfo invoker_info = ie.EventHandlerType.GetMethod ("Invoke");
ParameterInfo [] event_params = invoker_info.GetParameters ();
Delegate d = null;
Type stype = subscriber.GetType ();
MethodInfo [] methods = stype.GetMethods (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance);
MethodInfo candidate = null;
bool name_match = false;
for (int i = 0; i < methods.Length; i++) {
MethodInfo m = methods [i];
ParameterInfo [] parameters;
if (m.Name != handler_name)
continue;
if (name_match) {
error = "Multiple candidates with the same name found for event handler.";
// Console.WriteLine (error);
return false;
}
name_match = true;
if (m.ReturnType != typeof (void))
continue;
parameters = m.GetParameters ();
if (parameters.Length != event_params.Length)
continue;
bool match = true;
for (int p = 0; p < parameters.Length; p++) {
if (!event_params [p].ParameterType.IsSubclassOf (parameters [p].ParameterType) && parameters [p].ParameterType != event_params [p].ParameterType) {
Console.WriteLine ("mismatch: {0} and {1}", parameters [p].ParameterType, event_params [p].ParameterType);
match = false;
break;
}
}
if (!match)
continue;
if (candidate != null) {
error = "Multiple candidates for event handler found.";
// Console.WriteLine (error);
return false;
}
candidate = m;
}
if (candidate == null) {
error = "Event handler not found.";
// Console.WriteLine (error);
return false;
}
d = Delegate.CreateDelegate (ie.EventHandlerType, subscriber, candidate, false);
if (d == null) {
Console.Error.WriteLine ("ManagedXamlLoader::HookupEvent ({0}, {1}, {2}): unable to create delegate (src={3} target={4}).", (IntPtr) data->top_level, name, (IntPtr)value_ptr, ie.EventHandlerType, publisher);
error = "Can not create even delegate.";
return false;
}
// Console.Error.WriteLine ("ManagedXamlLoader::HookupEvent ({0}, {1}, {2}): Successfully created delegate (src={3} target={4}).", (IntPtr) data->top_level, name, value_ptr, ie.EventHandlerType, publisher);
error = null;
ie.AddEventHandler (publisher, d);
return true;
}