using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Tango.Core; using Tango.FSE.Common; namespace Tango.FSE.Procedures.Dialogs { public class UserInputDialogViewVM : FSEDialogViewVM { public class Parameter { public PropertyInfo PropertyInfo { get; set; } public FieldInfo FieldInfo { get; set; } public String Name { get; set; } public String Value { get; set; } public String TypeName { get { if (PropertyInfo != null) { return PropertyInfo.PropertyType.Name; } else if (FieldInfo != null) { return FieldInfo.FieldType.Name; } return null; } } public Type Type { get { if (PropertyInfo != null) { return PropertyInfo.PropertyType; } else if (FieldInfo != null) { return FieldInfo.FieldType; } else { return null; } } } public bool IsEnum { get { return Type == null? false: Type.IsEnum; } } public void SetValue(Object obj, Object value) { if (PropertyInfo != null) { PropertyInfo.SetValue(obj, value); } else if (FieldInfo != null) { FieldInfo.SetValue(obj, value); } } public Object GetValue(Object obj) { if (PropertyInfo != null) { return PropertyInfo.GetValue(obj); } else if (FieldInfo != null) { return FieldInfo.GetValue(obj); } return null; } } public String Title { get; set; } public String Message { get; set; } public List Parameters { get; set; } public Object Model { get; set; } public UserInputDialogViewVM(String title, String message, Object model) { CanClose = false; Title = title; Message = message; Parameters = new List(); Model = model; } public void Init() { try { if (Model.GetType().IsValueTypeOrString()) { Parameter p = new Parameter(); p.Value = Model.ToStringSafe(); p.Name = "Value"; Parameters.Add(p); } else { foreach (var prop in Model.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) { var att = prop.GetCustomAttribute(); Parameter p = new Parameter(); p.PropertyInfo = prop; p.Name = att != null ? att.Name : prop.Name.ToTitle(); if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(String)) { List objects = new List(); foreach (var item in prop.GetValue(Model) as IEnumerable) { objects.Add(item.ToStringSafe()); } p.Value = String.Join(",", objects); } else { p.Value = prop.GetValue(Model).ToStringSafe(); } Parameters.Add(p); } foreach (var field in Model.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)) { var att = field.GetCustomAttribute(); Parameter p = new Parameter(); p.FieldInfo = field; p.Name = att != null ? att.Name : field.Name.ToTitle(); if (typeof(IEnumerable).IsAssignableFrom(field.FieldType) && field.FieldType != typeof(String)) { List objects = new List(); foreach (var item in field.GetValue(Model) as IEnumerable) { objects.Add(item.ToStringSafe()); } p.Value = String.Join(",", objects); } else { p.Value = field.GetValue(Model).ToStringSafe(); } Parameters.Add(p); } } } catch (Exception ex) { throw new Exception("Error initializing the user input model.", ex); } } public void FinalizeModel() { if (Model.GetType().IsValueTypeOrString()) { Model = Convert.ChangeType(Parameters.First().Value, Model.GetType()); } else { foreach (var p in Parameters) { try { if (typeof(IEnumerable).IsAssignableFrom(p.Type) && p.Type != typeof(String)) { List items = p.Value.Split(',').ToList(); Type genericType = p.Type.GenericTypeArguments[0]; IList list = p.GetValue(Model) as IList; list.Clear(); foreach (var item in items) { list.Add(Convert.ChangeType(item, genericType)); } } else { if (p.Type.IsEnum) { var enumValue = Enum.Parse(p.Type, p.Value.ToString()); p.SetValue(Model, enumValue); } else { p.SetValue(Model, Convert.ChangeType(p.Value, p.Type)); } } } catch (Exception ex) { throw new ArgumentException($"Error setting the value '{p.Value}' for parameter '{p.Name}' of type '{p.Type.Name}'.", ex); } } } } } }