dotnet/maui · error · BuildException

XC0002

XC0002

Error message

EventHandler "{0}" with correct signature not found in type "{1}".

What it means

Thrown when wiring an event in XAML (e.g. `Clicked="Handler"`) and the compiler finds no method on the declaring type whose name matches and whose signature matches the event delegate's Invoke (return type and parameter types). The AllMethods search returns no match, so MissingEventHandler is thrown.

Source

Thrown at src/Controls/src/Build.Tasks/SetPropertiesVisitor.cs:1485

				//check if the handler signature matches the Invoke signature;
				var invoke = module.ImportReference(eventinfo.EventType.ResolveCached(context.Cache).GetMethods().First(eventmd => eventmd.Name == "Invoke"));
				invoke = invoke.ResolveGenericParameters(eventinfo.EventType, module);
				if (!md.methodDef.ReturnType.InheritsFromOrImplements(context.Cache, invoke.ReturnType) || invoke.Parameters.Count != md.methodDef.Parameters.Count)
					return false;

				if (!invoke.ContainsGenericParameter)
					for (var i = 0; i < invoke.Parameters.Count; i++)
						if (!invoke.Parameters[i].ParameterType.InheritsFromOrImplements(context.Cache, md.methodDef.Parameters[i].ParameterType))
							return false;
				//TODO check generic parameters if any

				return true;
			});
			MethodReference handlerRef = null;
			if (methodDef != null)
				handlerRef = methodDef.ResolveGenericParameters(declTypeRef, module);
			if (methodDef == null)
				throw new BuildException(MissingEventHandler, iXmlLineInfo, null, value, declaringType);

			//FIXME: eventually get the right ctor instead fo the First() one, just in case another one could exists (not even sure it's possible).
			var ctor = module.ImportReference(eventinfo.EventType.ResolveCached(context.Cache).GetConstructors().First());
			ctor = ctor.ResolveGenericParameters(eventinfo.EventType, module);

			if (methodDef.IsStatic)
			{
				yield return Create(Ldnull);
			}
			else
			{
				if (context.Root is VariableDefinition)
					foreach (var instruction in (context.Root as VariableDefinition).LoadAs(context.Cache, ctor.Parameters[0].ParameterType.ResolveGenericParameters(ctor), module))
						yield return instruction;
				else if (context.Root is FieldDefinition)
				{
					yield return Create(Ldarg_0);
					yield return Create(Ldfld, context.Root as FieldDefinition);

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Add a method with the matching name and signature, typically `void Handler(object sender, EventArgs e)` (or the event's specific EventArgs type).
  2. Ensure the method is accessible from the XAML's code-behind type (the declaring type).
  3. Correct any typo in the handler name referenced in XAML.

Example fix

<!-- before -->
<Button Clicked="OnClikc" />

<!-- after -->
<Button Clicked="OnClick" />

// code-behind
void OnClick(object sender, EventArgs e) { /* ... */ }
Defensive patterns

Strategy: validation

Validate before calling

// Verify a handler matching an event delegate exists on the code-behind type
static bool HandlerExists(Type owner, Type delegateType, string handlerName)
    => owner.GetMethods().Any(m => m.Name == handlerName && DelegateCompatible(m, delegateType));

static bool DelegateCompatible(System.Reflection.MethodInfo m, Type delegateType)
{
    var invoke = delegateType.GetMethod("Invoke");
    return m.ReturnType == invoke.ReturnType
        && m.GetParameters().Select(p => p.ParameterType)
            .SequenceEqual(invoke.GetParameters().Select(p => p.ParameterType));
}

Prevention

When it happens

Trigger: An event handler referenced in XAML is missing, renamed, has the wrong parameter list, is inaccessible, or its signature does not match the event's delegate (e.g. custom EventArgs).

Common situations: Typo in the handler name; handler deleted during refactor; method is private to a different type; using `(object, EventArgs)` for an event that expects a specific EventArgs subclass (still matches), or a non-matching custom delegate.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/c222f2b1110ae392. Report an issue: GitHub.