72 lines
2.1 KiB
C#
72 lines
2.1 KiB
C#
using System.Reflection;
|
|
using System.Windows.Markup;
|
|
using System.Windows;
|
|
using System.Xaml;
|
|
|
|
namespace TheXamlGuy.UI.WPF;
|
|
|
|
[MarkupExtensionReturnType(typeof(Delegate))]
|
|
public class TriggerExtension : MarkupExtension
|
|
{
|
|
public DependencyObject? TargetObject { get; protected set; }
|
|
|
|
protected object? TargetInvoke { get; private set; }
|
|
|
|
public void Invoke(object sender, EventArgs args)
|
|
{
|
|
OnInvoked(sender, args);
|
|
}
|
|
|
|
public override object ProvideValue(IServiceProvider serviceProvider)
|
|
{
|
|
if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target)
|
|
{
|
|
if (TargetObject is null)
|
|
{
|
|
if (target.TargetObject is DependencyObject dependencyObject)
|
|
{
|
|
TargetObject = dependencyObject;
|
|
}
|
|
else if (serviceProvider.GetService(typeof(IRootObjectProvider)) is IRootObjectProvider root)
|
|
{
|
|
TargetObject = (DependencyObject)root.RootObject;
|
|
}
|
|
}
|
|
|
|
TargetInvoke = target.TargetProperty;
|
|
|
|
MethodInfo invokeMethod = GetType().GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public)!;
|
|
if (invokeMethod is null)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
switch (TargetInvoke)
|
|
{
|
|
case EventInfo info:
|
|
return Delegate.CreateDelegate(info.EventHandlerType!, this, invokeMethod);
|
|
case MethodInfo methodInfo:
|
|
{
|
|
if (methodInfo.GetParameters() is ParameterInfo[] methodParameters && methodParameters is { Length: 2 })
|
|
{
|
|
return Delegate.CreateDelegate(methodParameters[1].ParameterType, this, invokeMethod);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
protected virtual void OnInvoked(object sender, EventArgs args)
|
|
{
|
|
|
|
}
|
|
}
|