public override object ProvideValue(IServiceProvider serviceProvider)
{
// Validates the argument
if (serviceProvider == null)
throw new ArgumentNullException(nameof(serviceProvider));
// Uses the service provider to retrieve a target provider, which is able to provide the target property to which the command is to be bound, if the target provider is null, an invalid operation exception is thrown
IProvideValueTarget targetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (targetProvider == null)
throw new InvalidOperationException(Resources.Localization.Markup.CommandBindingExtension.TargetProviderNullExceptionMessage);
// The target property could either be a plain old .NET event or a WPF routed event, in case of the .NET event, the target property is the event itself, in case of the WPF routed event, the target property is the AddHandler
// method of the routed event, both target properties are retrieved, the one that is not null is the right target property
EventInfo targetEventInfo = targetProvider.TargetProperty as EventInfo;
MethodInfo targetAddHandlerMethodInfo = targetProvider.TargetProperty as MethodInfo;
// Checks whether the target property is a .NET event or a WPF routed event and retrieves the type of the delegate for the event handler accordingly, which
// is used to generate a delegate, that is returned
Type delegateType;
if (targetEventInfo != null)
{
// The target property is a .NET event, so retrieve the delegate type accordingly
delegateType = targetEventInfo.EventHandlerType;
}
else if (targetAddHandlerMethodInfo != null)
{
// The target property is a WPF routed event, so retrieve a delegate tye
ParameterInfo[] parameters = targetAddHandlerMethodInfo.GetParameters();
delegateType = parameters[1].ParameterType;
}
else
{
// The target property is not event at all, so an invalid operation exception is raised
throw new InvalidOperationException(Resources.Localization.Markup.CommandBindingExtension.TargetPropertyNoEventExceptionMessage);
}
// Creates the delegate, which is returned as the value
MethodInfo methodInfo = this.GetType().GetMethod("InvokeCommandEventHandler", BindingFlags.NonPublic | BindingFlags.Instance);
return Delegate.CreateDelegate(delegateType, this, methodInfo);
}