ChangeAttachedPropertyAction
行为库的 ChangePropertyAction 只支持依赖属性,不支持附加属性。所以如果想要改变附加属性的值,就需要自定义一个 ChangeAttachedPropertyAction。
using Microsoft.Xaml.Behaviors;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
public class ChangeAttachedPropertyAction : TargetedTriggerAction<UIElement>
{
public Type? ClassType
{
get { return (Type)GetValue(ClassTypeProperty); }
set { SetValue(ClassTypeProperty, value); }
}
public static readonly DependencyProperty ClassTypeProperty = DependencyProperty.Register(
nameof(ClassType),
typeof(Type),
typeof(ChangeAttachedPropertyAction),
new PropertyMetadata(null)
);
public string? PropertyName
{
get => (string)GetValue(PropertyNameProperty);
set => SetValue(PropertyNameProperty, value);
}
public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register(
nameof(PropertyName),
typeof(string),
typeof(ChangeAttachedPropertyAction),
new PropertyMetadata("")
);
public object? Value
{
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
nameof(Value),
typeof(object),
typeof(ChangeAttachedPropertyAction),
new PropertyMetadata(null)
);
protected override void Invoke(object parameter)
{
ArgumentNullException.ThrowIfNull(ClassType, nameof(ClassType));
ArgumentException.ThrowIfNullOrEmpty(PropertyName, nameof(PropertyName));
MethodInfo setter =
ClassType.GetMethod($"Set{PropertyName}", BindingFlags.Static | BindingFlags.Public)
?? throw new ArgumentException($"Method {PropertyName} not found in {ClassType}");
Type parameterType = setter.GetParameters()[1].ParameterType;
if (parameterType.IsAssignableFrom(Value.GetType()))
{
setter.Invoke(null, [ Target, Value ]);
return;
}
var tc = TypeDescriptor.GetConverter(parameterType);
if (Value != null && tc.CanConvertFrom(Value.GetType()))
{
setter.Invoke(null, [ Target, tc.ConvertFrom(Value) ]);
return;
}
throw new ArgumentException($"Cannot convert {Value?.GetType()} to {parameterType}");
}
}