using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Interactivity;
namespace Tango.FSE.Common.EventTriggerActions
{
///
/// Sets a specified property to a value when invoked.
///
public class SetterAction : TargetedTriggerAction
{
#region Properties
#region PropertyName
///
/// Property that is being set by this setter.
///
public string PropertyName
{
get { return (string)GetValue(PropertyNameProperty); }
set { SetValue(PropertyNameProperty, value); }
}
public static readonly DependencyProperty PropertyNameProperty =
DependencyProperty.Register("PropertyName", typeof(string), typeof(SetterAction),
new PropertyMetadata(String.Empty));
#endregion
#region Value
///
/// Property value that is being set by this setter.
///
public object Value
{
get { return (object)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(object), typeof(SetterAction),
new PropertyMetadata(null));
#endregion
#endregion
#region Overrides
protected override void Invoke(object parameter)
{
var target = TargetObject ?? AssociatedObject;
var targetType = target.GetType();
var property = targetType.GetProperty(PropertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
if (property == null)
throw new ArgumentException(String.Format("Property not found: {0}", PropertyName));
if (property.CanWrite == false)
throw new ArgumentException(String.Format("Property is not settable: {0}", PropertyName));
object convertedValue;
if (Value == null)
convertedValue = null;
else
{
var valueType = Value.GetType();
var propertyType = property.PropertyType;
if (valueType == propertyType)
convertedValue = Value;
else
{
var propertyConverter = TypeDescriptor.GetConverter(propertyType);
if (propertyConverter.CanConvertFrom(valueType))
convertedValue = propertyConverter.ConvertFrom(Value);
else if (valueType.IsSubclassOf(propertyType))
convertedValue = Value;
else
throw new ArgumentException(String.Format("Cannot convert type '{0}' to '{1}'.", valueType, propertyType));
}
}
property.SetValue(target, convertedValue);
}
#endregion
}
}