Advertisement
Guest User

Custom Property List Attribute

a guest
Aug 5th, 2014
605
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.55 KB | None | 0 0
  1. using System; using System.Collections.Generic; using System.ComponentModel;
  2. using System.Windows.Forms; using System.Windows.Forms.Design; using System.Drawing.Design;
  3. using System.Reflection; namespace Fire {
  4. //TODO: Threading
  5. //##################################################################################################
  6. public abstract class PropsAttrBase: Attribute {
  7. string names; public string Names { get { return names; } set { names = value; } }
  8. public PropsAttrBase(string names) {
  9.     this.names = names; }}
  10. //##################################################################################################
  11. [AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct, AllowMultiple=false, Inherited=true)]
  12. public class PropsAttribute: PropsAttrBase {
  13. public PropsAttribute(string names): base(names) {}
  14. //##################################################################################################
  15. public static void ClearPropDescs() { init(propDescs); }
  16. public static PropertyDescriptorCollection GetProps(Type type) {
  17.     return new PropertyDescriptorCollection(GetDescs(type)); }
  18. private static readonly PropertyDescriptor[] emptyPropDescs = TYPE<PropertyDescriptor>.EmptyArray;
  19. private static readonly Dictionary<Type, PropertyDescriptor[]> propDescs = create();
  20. private static Dictionary<Type, PropertyDescriptor[]> create() {
  21.     return init(new Dictionary<Type, PropertyDescriptor[]>()); }
  22. private static Dictionary<Type, PropertyDescriptor[]> init(Dictionary<Type, PropertyDescriptor[]> it) {
  23.     it.Clear(); it[typeof(string)] = emptyPropDescs; return it; }
  24. private static string[] stdnlist = new string[] { "..", "." };
  25. public static PropertyDescriptor[] GetDescs(Type type) {
  26.     if(type == null || type.IsPrimitive) return emptyPropDescs;
  27.     PropertyDescriptor[] props;
  28.     if(!propDescs.TryGetValue(type, out props)) {
  29.         string names = null;
  30.         PropsAttrBase attr = type.GetAttribute<PropsAttribute>(false);
  31.         if(attr == null) attr = type.GetAttribute<PropsAttrBase>(false);
  32.         if(attr != null) names = attr.Names;
  33.         if(names != null && names.Length == 0) {
  34.             props = emptyPropDescs;
  35.             propDescs[type] = props;
  36.             return props; }
  37.         string[] nlist = names != null ? names.SplitList() : stdnlist;
  38.         List<PropertyDescriptor> list = new List<PropertyDescriptor>(nlist.Length);
  39.         Dictionary<string, int> dict = new Dictionary<string, int>();
  40.         PropertyDescriptor pd;
  41.         foreach(string name in nlist) {
  42.             if(name == "..") {
  43.             //  base properties
  44.                 foreach(PropertyDescriptor desc in GetDescs(type.BaseType))
  45.                     if(!dict.ContainsKey(desc.Name)) { dict.Add(desc.Name, list.Count); list.Add(desc); }
  46.             } else if(name == "." || name == "...") {
  47.             //  new properties
  48.                 foreach(PropertyInfo pi in type.GetProperties(BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.Instance)) {
  49.                     if(!pi.CanRead) continue;
  50.                     BrowsableAttribute ba = pi.GetAttribute<BrowsableAttribute>();
  51.                     if(ba != null && ba.Browsable == false) continue;
  52.                     try { pd = TypeDescriptor.CreateProperty(type, pi.Name, pi.PropertyType);
  53.                     } catch { pd = new NonexistentProperty(type, pi.Name); }
  54.                     if(dict.ContainsKey(pd.Name)) list[dict[pd.Name]] = pd;
  55.                     else { dict.Add(pd.Name, list.Count); list.Add(pd); }}
  56.             } else {
  57.             //  selected property
  58.                 string pname = name;
  59.                 bool remove = name[0] == '-';
  60.                 if(remove) pname = name.Substring(1);
  61.                 try {
  62.                     PropertyInfo pi = type.GetProperty(pname, BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.FlattenHierarchy);
  63.                     if(pi == null) pi = type.GetProperty(pname, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.FlattenHierarchy);
  64.                     pd = TypeDescriptor.CreateProperty(type, pname, pi.PropertyType);
  65.                 } catch { if(remove) continue; pd = new NonexistentProperty(type, pname); }
  66.                 pname = pd.Name;
  67.                 if(dict.ContainsKey(pname)) {
  68.                     int idx = dict[pname];
  69.                     if(!remove) list[idx] = pd;
  70.                     else {
  71.                         list.RemoveAt(idx);
  72.                         dict.Remove(pname);
  73.                         FireList<string> keys = new FireList<string>();
  74.                         foreach(string key in dict.Keys) {
  75.                             int val = dict[key];
  76.                             if(val > idx) keys.Add(key); }
  77.                         foreach(string key in keys)
  78.                             dict[key] = dict[key]-1; }
  79.                 } else if(!remove) { dict.Add(pname, list.Count); list.Add(pd); }}}
  80.         props = list.Count > 0 ? list.ToArray() : emptyPropDescs;
  81.         propDescs[type] = props; }
  82.     return props; }
  83. //##################################################################################################
  84. public class NonexistentProperty: PropertyDescriptor {
  85.     protected Type type, propType;
  86.     public NonexistentProperty(Type type, string name, Type propType, Attribute[] attrs) : base(name, attrs) { this.type = type; this.propType = propType; }
  87.     public NonexistentProperty(Type type, string name) : this(type, name, typeof(string), TYPE<Attribute>.EmptyArray) { }
  88.     public override object GetValue(object component) { return Name + " does not exist"; }
  89.     public override Type ComponentType { get { return type; } }
  90.     public override Type PropertyType { get { return propType; } }
  91.     public override bool CanResetValue(object component) { return false; }
  92.     public override bool IsReadOnly { get { return true; } }
  93.     public override bool ShouldSerializeValue(object component) { return false; }
  94.     public override void ResetValue(object component) { }
  95.     public override void SetValue(object component, object value) {}
  96. }}}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement