/// <summary> /// Construct a new object LimeProperty /// </summary> /// <param name="ident">identifier of the LimeProperty</param> /// <param name="source">object to be referenced</param> /// <param name="path">identifier of the property</param> /// <param name="reference">Reference the object if true, create independent object if false</param> /// <param name="name">User-friendly name of the object. Automatically taken from translation by default.</param> /// <param name="readOnly">Define readOnly attribute</param> /// <param name="visible">Define visibility to the user</param> public LimeProperty(string ident, object source, string path = null, string name = null, bool?readOnly = null, bool?visible = null) { PropertyInfo pi; LimePropertyAttribute attr = null; if (path != null) { pi = source.GetType().GetProperty(path); var attribs = pi.GetCustomAttributes(typeof(LimePropertyAttribute), true); if (attribs != null && attribs.Length > 0) { attr = (LimePropertyAttribute)attribs[0]; } if (ident == null) { ident = path; } } else { pi = null; } Factory(ident, source, pi, attr, name, readOnly, visible); }
/// <summary> /// Construct the class by copying from another object. /// </summary> /// <param name="attr">base attribute to copy to the new one</param> public LimePropertyAttribute(LimePropertyAttribute attr) { if (attr != null) { LimeLib.CopyPropertyValues(attr, this); } }
// -------------------------------------------------------------------------------------------------- #region ctors /// <summary> /// Create a Collection to contain LimeProperty from any source object /// </summary> /// <param name="mode">StringComparer defining the Sorting mode by LimeProperty identifiers (null: declaration order)</param> /// <param name="source">Source collection or class to make the LimeProperty from</param> /// <param name="attr">LimePropertyAttribute to apply to the items in the collection</param> /// <param name="all">Take all public objects if true, only Xml or LimePropertyAttribute visible elements is false</param> public LimePropertyCollection(StringComparer mode, object source = null, LimePropertyAttribute attr = null, bool all = true) { StringComparer = mode; Source = source; if (source == null) { return; } // Unpack LimePropertyAttribute if (attr == null && source is LimePropertyAttribute psrc) { if (attr == null) { attr = psrc; } } // Unpack IMatryoshka, LimeProperty if (source is IMatryoshka matr) { source = matr.Content; if (source == null) { return; } } // Force the LimePropertyAttribute to be *only* a LimePropertyAttribute (otherwises it will copy all the object) if (attr != null && attr.GetType() != typeof(LimePropertyAttribute)) { attr = new LimePropertyAttribute(attr); } if (source is IEnumerable enumerable) { foreach (var item in enumerable) { var prop = item as LimeProperty; if (prop == null) { prop = new LimeProperty(null, item, null, attr); } Add(prop); } } else { AddContent(source, attr, all); } }
/// <summary> /// Construct a reference to a property in a class /// </summary> /// <param name="ident">identifier of the LimeProperty</param> /// <param name="source">Object to be referenced</param> /// <param name="pi">PropertyInfo of the property</param> /// <param name="attr">Configuration attributes attached to this property</param> /// <param name="name">User-friendly name of the object. Automatically taken from translation by default.</param> public LimeProperty(string ident, object source, PropertyInfo pi, LimePropertyAttribute attr, string name = null) { Factory(ident, source, pi, attr, name); }
// -------------------------------------------------------------------------------------------------- #region ctors /// <summary> /// Construct a reference to a property in a class /// </summary> /// <param name="ident">identifier of the LimeProperty</param> /// <param name="source">Parent object of the class where the property belongs</param> /// <param name="pi">PropertyInfo of the property (null if not referenced)</param> /// <param name="attr">Configuration attributes attached to this property</param> /// <param name="name">User-friendly name of the object. Automatically taken from translation by default.</param> /// <param name="readOnly">Define readOnly attribute</param> /// <param name="visible">Define visibility to the user</param> private void Factory(string ident, object source, PropertyInfo pi, LimePropertyAttribute attr, string name = null, bool?readOnly = null, bool?visible = null) { LimeLib.LifeTrace(this); Source = source; string languageSection = IniLanguageSection; if (pi != null) { // Referenced source PInfo = pi; var vobj = pi.GetValue(Source); Type = vobj != null?vobj.GetType() : pi.PropertyType; Ident = ident ?? pi.Name; } else { // Unreferenced source Type = source.GetType(); Ident = ident; } // Implied attributes if (source is System.Windows.Input.ICommand) { ReadOnly = true; languageSection = IniLanguageCommand; } // Copy attribute if (attr != null) { if (attr.GetType() != typeof(LimePropertyAttribute)) { attr = new LimePropertyAttribute(attr); } LimeLib.CopyPropertyValues(attr, this); } // Forced attributes if (readOnly != null) { ReadOnly = readOnly == true; } if (visible != null) { Visible = visible == true; } // Bind the object if (source is INotifyPropertyChanged src) { //LimeMsg.Debug("LimeProperty Factory: Subscribe {0} / {1}", Ident, src); src.PropertyChanged += SourcePropertyChanged; } if (Ident == null || name != null || !Visible) { Name = name ?? ident; Desc = null; } else { // Retrieve properties from LimeLanguage Name = LimeLanguage.Translate(languageSection, Ident + ".name", Ident); Desc = LimeLanguage.Translate(languageSection, Ident + ".desc", Name); } }
/// <summary> /// Add the content of any object to the collection. /// </summary> /// <param name="source">source object, class, collection...</param> /// <param name="attr">Default LimePropertyAttribute to apply to the items in the collection</param> /// <param name="all">Take all public objects if true, only Xml or LimePropertyAttribute visible elements is false</param> public void AddContent(object source, LimePropertyAttribute attr = null, bool all = true) { var field = source as Type; MemberInfo[] miSource; if (field != null) { miSource = field.GetFields(); } else { miSource = source.GetType().GetProperties(); } // Populate list foreach (var mi in miSource) { object[] attributes = mi.GetCustomAttributes(true); bool visible = all; LimePropertyAttribute cfgAttr = null; foreach (object attrib in attributes) { XmlElementAttribute xmlAttr = attrib as XmlElementAttribute; if (xmlAttr != null) { visible = true; } cfgAttr = attrib as LimePropertyAttribute; if (cfgAttr != null) { visible = cfgAttr.Visible; break; } } if (cfgAttr == null) { cfgAttr = attr; } if (visible) { if (all && (attr == null || attr.Visible) && mi is PropertyInfo pi) { string ident = string.Format("{0}.{1}", source.GetType().Name, mi.Name); string name = LimeLanguage.Translate(IniLanguageSection, ident + ".name", mi.Name); var prop = new LimeProperty(null, source, pi, cfgAttr, name); prop.Desc = LimeLanguage.Translate(IniLanguageSection, ident + ".desc", name); Add(prop); } else if (mi is PropertyInfo pi2) { Add(new LimeProperty(null, source, pi2, cfgAttr)); } else if (mi is FieldInfo fi) { var obj = fi.GetValue(field); Add(new LimeProperty(mi.Name, obj)); } else { throw new Exception("LimePropertyCollection AddContent: Unuspported type"); } } } }