using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using Tango.Core; using Tango.Core.CustomAttributes; /// /// Contains extension methods for . /// public static class IParameterizedExtensions { /// /// Creates an observable collection of the parameterized object. /// /// The instance. /// The parameters update mode. /// public static ObservableCollection CreateParametersCollection(this IParameterized instance, ParameterItemMode mode) { var ps = new ObservableCollection(); int index = 0; List types = new List(); Type currentType = instance.GetType(); while (true) { if (typeof(IParameterized).IsAssignableFrom(currentType) && currentType != typeof(IParameterized)) { types.Add(currentType); currentType = currentType.BaseType; } else { break; } } List properties = new List(); foreach (var type in types) { foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(x => x.SetMethod != null)) { if (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(String) || prop.PropertyType == typeof(DateTime)) { var paramAtt = prop.GetCustomAttributes(typeof(ParameterItemAttribute), false).Cast().FirstOrDefault(); var ignore = prop.GetCustomAttributes(typeof(ParameterIgnoreAttribute), false).Cast().FirstOrDefault(); var indexAttr = prop.GetCustomAttributes(typeof(PropertyIndexAttribute), false).Cast().FirstOrDefault(); if (ignore == null && !properties.Exists(x => x.Name == prop.Name)) { var item = instance.CreateParameterItem(prop, paramAtt,indexAttr != null ? indexAttr.Index : index++, mode); ps.Add(item); properties.Add(prop); } } } } return ps.OrderBy(x => x.Index).ToObservableCollection(); } /// /// Creates the parameter item. /// /// The instance. /// The property information. /// The attribute. /// The index. /// The mode. /// public static ParameterItem CreateParameterItem(this IParameterized instance, PropertyInfo propertyInfo, ParameterItemAttribute attribute, int index, ParameterItemMode mode) { ParameterItem item = new ParameterItem(); item.Name = propertyInfo.Name.ToTitle(); item.Index = index; item.Type = propertyInfo.PropertyType; item.ParameterizedObject = instance; if (attribute != null) { item.Value = attribute.Default; item.Minimum = attribute.Minimum; item.Maximum = attribute.Maximum; item.CustomEditorTypeName = attribute.CustomEditorTypeName; item.ExtraObject = attribute.ExtraObject; if (attribute.Name != null) { item.Name = attribute.Name; } } else { //Try get description and range attributes DescriptionAttribute desAtt = propertyInfo.GetCustomAttribute(); if (desAtt != null) { item.Description = desAtt.Description; } RangeAttribute rangeAtt = propertyInfo.GetCustomAttribute(); if (rangeAtt != null) { item.Minimum = rangeAtt.Minimum; item.Maximum = rangeAtt.Maximum; } StringFormatAttribute formatAtt = propertyInfo.GetCustomAttribute(); if (formatAtt != null) { item.StringFormat = formatAtt.Format; } PropertyIndexAttribute indexAtt = propertyInfo.GetCustomAttribute(); if (indexAtt != null) { item.Index = indexAtt.Index; } } if (mode == ParameterItemMode.Event) { item.ParameterValueChanged += (sender, e) => { propertyInfo.SetValue(instance, e.Value); }; } else if (mode == ParameterItemMode.Binding) { item.Bind(ParameterItem.ValueProperty, instance, propertyInfo.Name, System.Windows.Data.BindingMode.TwoWay); } return item; } /// /// Creates the parameter item. /// /// The instance. /// Name of the property. /// The attribute. /// The index. /// The mode. /// public static ParameterItem CreateParameterItem(this IParameterized instance, String propertyName, ParameterItemAttribute attribute, int index, ParameterItemMode mode) { return instance.CreateParameterItem(instance.GetType().GetProperty(propertyName), attribute, index, mode); } }