using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.ComponentModel; namespace VEPROMS.CSLA.Library { #region vlnFormatDocument public class vlnFormatDocument:XmlDocument { private static XmlElement mydocele; public vlnFormatDocument(IFormatOrFormatInfo myFormat) { _MyFormat = myFormat; LoadXml(MyFormat.Data); mydocele = this.DocumentElement; } private IFormatOrFormatInfo _MyFormat; public IFormatOrFormatInfo MyFormat { get { return _MyFormat; } set { _MyFormat = value; } } public static XmlNode LookupSingleNode(XmlNode xmlNode, string path) { //original: //if (xmlNode == null) return null; //XmlNode xn = xmlNode.SelectSingleNode(path); //if (xn != null) return xn; //if (xmlNode.Name == "Step") xn = LookupSingleStepNode(xmlNode, path); //if (xn != null) return xn; //if (path.StartsWith("Font")) return LookupSingleFontNode(xmlNode, path); //return InheritLookup(xmlNode, path); /* RHM 20090821 - if (path.StartsWith("Font")) { XmlNode xn = null; if (xmlNode != null) { xn = xmlNode.SelectSingleNode(path); // RHM 2008-12-15 - Added logic to keep looking if a blank attribute is found if (xn != null && xn is XmlAttribute && (xn as XmlAttribute).Value != "") return xn; //if (xn != null) return xn; } else { xmlNode = LookupSingleNode(mydocele.FirstChild, "/PlantFormat/FormatData"); } if (path.Contains("Font")) Console.WriteLine("vlnFormatDocument.LookupSingleNode {0},{1}", xmlNode.Name == "Step" ? "Step." + xmlNode.Attributes["Type"].Value : xmlNode.Name, path); return LookupSingleFontNode(xmlNode, path); } else { */ if (xmlNode == null) return null; XmlNode xn = xmlNode.SelectSingleNode(path); if (xmlNode.Name == "Box") return xn; // if box, don't do inheritance. if (xmlNode.Name == "DocStyle") return xn; //C2025-023 - Electronic Procedures - Modifications to PROMS if (xmlNode.Name == "EPField") return xn; // if Electronic Procedure Field, don't do inheritance. if (xmlNode.Name == "StructureStyle") { Volian.Base.Library.DebugText.WriteLine("vlnFormatDocument:LookupSingleNode:StructureStyle - shouldn't get to this line of code.\r\nPath = {0}", path); return xn; // User Format (sub format) - shouldn't? inherit? -need to check } if (xn != null) return xn; //if (path.Contains("Font")) Console.WriteLine("vlnFormatDocument.LookupSingleNode {0},{1}", xmlNode.Name == "Step" ? "Step." + xmlNode.Attributes["Type"].Value : xmlNode.Name, path); if (xmlNode.Name == "Step") xn = LookupSingleStepNode(xmlNode, path); // Check for Step Inheritance if (xmlNode.ParentNode.Name == "Step") xn = LookupSingleStepNode(xmlNode.ParentNode, xmlNode.Name + "/" + path); // Check for Step Inheritance if (xn != null) return xn; if (path.StartsWith("Font")) return LookupSingleFontNode(xmlNode, path); // Then do Font Inheritance return InheritLookup(xmlNode, path, false); // } } public static XmlNode LookupSingleFontNode(XmlNode xmlNode, string path) { if (xmlNode == null) return null; XmlNode tmpNode = xmlNode; XmlNode xn = xmlNode.SelectSingleNode(path); // RHM 2008-12-15 - Added logic to keep looking if a blank attribute is found while (xn == null || (xn is XmlAttribute && (xn as XmlAttribute).Value == ""))//Walk-up the format tree to find a font node { // if the font is not specified in the PageStyle (PageList), then see if oneis set in the DocStyle (default for that section) // if (xmlNode.Name == "PageStyle") { string psIdx = (xmlNode.Attributes.GetNamedItem("Index") as XmlAttribute).Value; XmlNode docStyle = xmlNode.OwnerDocument.SelectSingleNode(string.Format("//DocStyle[@PageStyle='{0}']",psIdx)); xn = docStyle.SelectSingleNode(path); if (xn != null) return xn; // could not find a font in the DocStyle, so use the format default return LookupSingleNode(tmpNode.OwnerDocument.DocumentElement, "/PlantFormat/FormatData/" + path); } if (xmlNode.NodeType == XmlNodeType.Document) { //if (path.Contains("Font")) Console.WriteLine("vlnFormatDocument.LookupSingleFontNode {0},{1}", tmpNode.Name == "Step" ? "Step." + tmpNode.Attributes["Type"].Value : tmpNode.Name, path); return LookupSingleNode(tmpNode.OwnerDocument.DocumentElement, "/PlantFormat/FormatData/" + path); } xmlNode = xmlNode.ParentNode; xn = xmlNode.SelectSingleNode(path); } return xn; } public static XmlNode LookupSingleStepNode(XmlNode xmlNode, string path) { if (xmlNode == null) return null; XmlNode xn = xmlNode.SelectSingleNode(path); XmlNode tmpNode = xmlNode; XmlNode tmpNode2 = xmlNode; while (xn == null) //Walk-up the format tree to find a step node { //if (path.Contains("Font")) Console.WriteLine("vlnFormatDocument.LookupSingleStepNode -> Loop {0},{1}", xmlNode.Name == "Step" ? "Step." + xmlNode.Attributes["Type"].Value : xmlNode.Name, path); tmpNode = xmlNode; // RHM 20090831 Try doing a lookup of the parent. If no parent, go back to the original and do an inheritance lookup XmlAttribute attr = xmlNode.Attributes["ParentType"]; if (attr == null || attr.Value == string.Empty) // Cannot find ParentType so do an InheritanceLookup return InheritLookup(tmpNode2, path, true); //return InheritLookup(xmlNode, path, false); xmlNode = xmlNode.ParentNode.SelectSingleNode(string.Format("Step[@Type='{0}']", xmlNode.Attributes["ParentType"].InnerText)); // Based upon our current data - the following conditions are never met. //if (xmlNode == null && path.StartsWith("Font")) //{ // //if (path.Contains("Font")) Console.WriteLine("vlnFormatDocument.LookupSingleStepNode -> Font {0},{1}", tmpNode.Name == "Step" ? "Step." + tmpNode.Attributes["Type"].Value : tmpNode.Name, path); // return LookupSingleFontNode(tmpNode, path); //} //if (xmlNode == null) //{ // //if (path.Contains("Font")) Console.WriteLine("vlnFormatDocument.LookupSingleStepNode -> Font {0},{1}", tmpNode2.Name == "Step" ? "Step." + tmpNode2.Attributes["Type"].Value : tmpNode2.Name, path); // return InheritLookup(tmpNode2, path, true); //} xn = xmlNode.SelectSingleNode(path); } return xn; } public static XmlNodeList LookupNodes(XmlNode xmlNode, string path) { if (xmlNode == null) return null; XmlNodeList xl = xmlNode.SelectNodes(path); if (xl == null||xl.Count==0) xl = InheritLookupNodes(xmlNode, path); if (xl == null) return null; return xl; } public static string Lookup(XmlNode xmlNode, string path) { //if (xmlNode == null) return null; XmlNode xn = LookupSingleNode(xmlNode, path); //if (xn == null) xn = InheritLookup(xmlNode, path); if (xn == null) return null; return xn.InnerText; } //public static string StepLookup(XmlNode xmlNode, string path) //{ // //if (xmlNode == null) return null; // XmlNode xn = LookupSingleStepNode(xmlNode, path); // //if (xn == null) xn = InheritLookup(xmlNode, path); // if (xn == null) return null; // return xn.InnerText; //} public static T EnumLookup(XmlNode xmlNode, string path) { string str = Lookup(xmlNode,path); if (str == null) return default(T); return (T)Enum.Parse(typeof(T), str); } public static int? IntLookup(XmlNode xmlNode, string path) { //if (xmlNode == null) return null; //XmlNode xn = LookupSingleNode(xmlNode, path); //if (xn == null) xn = InheritLookup(xmlNode, path); //if (xn == null) return null; //return int.Parse(xn.InnerText); string str = Lookup(xmlNode, path); if (str == null) return null; return int.Parse(str); } public static int SiblingCount(XmlNode xmlNode) { int retval = 0; string nodeName = xmlNode.Name; for (XmlNode xn = xmlNode; xn != null; xn = xn.PreviousSibling) { if (xn.Name == nodeName) retval++; } return retval; } public static string Path(XmlNode xmlNode) { // Walk the path string parentPath = (xmlNode.ParentNode == xmlNode.OwnerDocument ? "" : Path(xmlNode.ParentNode)); // Count Siblings with the Same Name int sibCount = SiblingCount(xmlNode); return string.Format("{0}/{1}[{2}]", parentPath, xmlNode.Name, sibCount); } public static XmlNode InheritLookup(XmlNode xmlNode, string path, bool stepLookup) { //stepLookup = false; // 8/2 change for inheritance if (xmlNode == null) return null;// No path to match string xPath = Path(xmlNode);// Build xPath from xmlNode if (xmlNode.Name == "TransTypes") { string TransIndex = xmlNode.Attributes["Index"].Value; xPath = System.Text.RegularExpressions.Regex.Replace(xPath, @"\[[0-9]*\]$", @"[@Index='" + TransIndex + @"']"); } vlnFormatDocument fd = (vlnFormatDocument)(xmlNode.OwnerDocument);//First Get the vlnFormatDocument - This also ties it to a FormatInfo object while(fd.MyFormat.MyIParent != null) { fd = fd.MyFormat.MyIParent.PlantFormat.XmlDoc;// Get the parents vlnFormatDocument if (fd != null) { XmlNode xp; if (path.StartsWith("/")) xp = fd.DocumentElement; else xp = fd.SelectSingleNode(xPath);// Get the related node if (xp != null) { XmlNode xn = null; if (stepLookup) { //if (path.Contains("Font")) Console.WriteLine("vlnFormatItem.SelectSingleNode {0},{1}", xp.Name == "Step" ? "Step." + xp.Attributes["Type"].Value : xp.Name, path); xn = LookupSingleStepNode(xp, path); } else xn = xp.SelectSingleNode(path); if(xn != null) return xn; } } } return null; } public static XmlNodeList InheritLookupNodes(XmlNode xmlNode, string path) { if (xmlNode == null) return null;// No path to match string xPath = Path(xmlNode);// Build xPath from xmlNode vlnFormatDocument fd = (vlnFormatDocument)(xmlNode.OwnerDocument);//First Get the vlnFormatDocument - This also ties it to a FormatInfo object while (fd.MyFormat.MyIParent != null) { fd = fd.MyFormat.MyIParent.PlantFormat.XmlDoc;// Get the parents vlnFormatDocument if (fd != null) { XmlNode xp = fd.SelectSingleNode(xPath);// Get the related node if (xp != null) { XmlNodeList xl = xp.SelectNodes(path); if (xl != null && xl.Count > 0) return xl; } } } return null; } } #endregion #region vlnFormatItem [TypeConverter(typeof(ExpandableObjectConverter))] public class vlnFormatItem { public vlnFormatItem(XmlNode xmlNode) { _XmlNode = xmlNode; } public vlnFormatItem() { } XmlNode _XmlNode; internal XmlNode XmlNode { get { return _XmlNode; } set { _XmlNode = value; } } private IFormatOrFormatInfo _MyFormat; public IFormatOrFormatInfo MyFormat { get { if (_MyFormat == null) { vlnFormatDocument doc = (XmlNode.OwnerDocument) as vlnFormatDocument; if(doc != null) _MyFormat = doc.MyFormat; } return _MyFormat; } } private IFormatOrFormatInfo _MyParentFormat; public IFormatOrFormatInfo MyParentFormat { get { return MyFormat.MyIParent; } } public virtual string GetPDDisplayName() { return ToString(); } public virtual string GetPDName() { return ToString(); } public virtual string GetPDDescription() { return ToString(); } public virtual string GetPDCategory() { return ToString(); } public XmlNodeList SelectNodes(string path) { return vlnFormatDocument.LookupNodes(_XmlNode, path); } public XmlNode SelectSingleNode(string path) { //AdjustLookup(_XmlNode, path); //if(path.Contains("Font")) Console.WriteLine("vlnFormatItem.SelectSingleNode {0},{1}", _XmlNode.Name == "Step" ? "Step." + _XmlNode.Attributes["Type"].Value : _XmlNode.Name, path); return vlnFormatDocument.LookupSingleNode(_XmlNode, path); } //public static string _LookUpNode; //private static void AdjustLookup(XmlNode xmlNode,string path) //{ // if (xmlNode.Name == "Step") // { // XmlAttribute attr = xmlNode.Attributes["Type"]; // if (attr != null) _LookUpNode = attr.Value; // //Console.WriteLine("AdjustLookup Type = {0}/{1}", _LookUpNode, path); // } // else // { // //Console.WriteLine("AdjustLookup {0}", xmlNode.Name); // } //} public XmlNode SelectSingleFontNode(string path) { return vlnFormatDocument.LookupSingleFontNode(_XmlNode, path); } public string Lookup(string path) { return vlnFormatDocument.Lookup(_XmlNode, path); } public string Lookup(string path, ref string local) { return (local != null? local : local = Lookup(path)); } //public string StepLookup(string path) //{ // return vlnFormatDocument.StepLookup(_XmlNode, path); //} public int? IntLookup(string path) { return vlnFormatDocument.IntLookup(_XmlNode, path); } public int? IntLookup(string path, ref int? local) { return (local != null ? local : local = IntLookup(path)); } public T EnumLookup(string path) { return vlnFormatDocument.EnumLookup(_XmlNode, path); } public bool LazyLoad(ref LazyLoad ll, string xPath) { if (ll == null) { XmlNode xn = SelectSingleNode(xPath); ll = new LazyLoad(RetrieveBool(xn)); } return ll.Value; } protected static bool RetrieveBool(XmlNode xn) { return xn != null && xn.InnerText.ToUpper() == "TRUE"; } // a LaxyLoad that allows you to pass in the default setting public bool LazyLoad(ref LazyLoad ll, string xPath, bool defaultReturn) { if (ll == null) { XmlNode xn = SelectSingleNode(xPath); ll = new LazyLoad(RetrieveBool(xn, defaultReturn)); } return ll.Value; } // if nothing is set for this node, then use the passed in default value protected static bool RetrieveBool(XmlNode xn, bool defaultReturn) { return (xn != null) ? xn.InnerText.ToUpper() == "TRUE" : defaultReturn; } public string LazyLoad(ref LazyLoad ll, string xPath) { if (ll == null) { XmlNode xn = SelectSingleNode(xPath); ll = new LazyLoad(RetrieveString(xn)); } return ll.Value; } protected static string RetrieveString(XmlNode xn) { return xn != null ? xn.InnerText : null; } public string MyPath { get { StringBuilder sb = new StringBuilder(); XmlNode node = _XmlNode; string prefix = ""; while (node != null) { sb.Insert(0, node.Name + prefix); prefix = "/"; node = node.ParentNode; } return sb.ToString(); } } public int? LazyLoad(ref LazyLoad ll, string xPath) { if (ll == null) { XmlNode xn = SelectSingleNode(xPath); ll = new LazyLoad(RetrieveInt(xPath, xn)); } return ll.Value; } public float? LazyLoad(ref LazyLoad ll, string xPath) { if (ll == null) { XmlNode xn = SelectSingleNode(xPath); ll = new LazyLoad(RetrieveFloat(xPath, xn)); } return ll.Value; } protected int? RetrieveInt(string xPath, XmlNode xn) { int? value = null; if (xn != null) { int iValue = 0; if (!int.TryParse(xn.InnerText, out iValue)) { if (xn.InnerText == "") return null; Console.WriteLine(string.Format("'{0}'\r\n'{1}'\r\n'{2}' could not be converted to int?", MyFormat.FullName, MyPath + "/" + xPath, xn.InnerText)); throw (new Exception(string.Format("{0} = '{1}' could not be converted to int?", xPath, xn.InnerText))); } value = iValue; } return value; } protected float? RetrieveFloat(string xPath, XmlNode xn) { float? value = null; if (xn != null) { float fValue = 0; if (!float.TryParse(xn.InnerText, out fValue)) { Console.WriteLine(string.Format("'{0}'\r\n'{1}'\r\n'{2}' could not be converted to float?", MyFormat.FullName, MyPath + "/" + xPath, xn.InnerText)); throw (new Exception(string.Format("{0} = '{1}' could not be converted to float?", xPath, xn.InnerText))); } value = fValue; } return value; } public Nullable LazyLoad(ref LazyLoad> ll, string xPath) where T:struct { if (ll == null) { XmlNode xn = this._XmlNode; xn = SelectSingleNode(xPath); if (xn == null) ll = new LazyLoad(null); else if (xn.Value == "")// No value specified - Use zero value if it is defined - GetName returns a null if it is not defined ll = new LazyLoad>(Enum.GetName(typeof(T), 0) != null ? (Nullable) Enum.Parse(typeof(T), "0") : null); else try { ll = new LazyLoad>((Nullable)Enum.Parse(typeof(T), xn.InnerText)); } catch (Exception ex) { Console.WriteLine("{0} - '{1}'", ex.Message, xn.InnerText); ll = new LazyLoad(null); } } return ll.Value; } } #endregion #region IVlnIndexedFormatItem public partial interface IVlnIndexedFormatItem { int? Index { get; } } #endregion #region IVlnNamedFormatItem public partial interface IVlnNamedFormatItem { string Name { get; } bool Inherited { get; } } #endregion #region LazyLoad public class LazyLoad { public LazyLoad(T value) { _Value = value; } private T _Value; public T Value { get { return _Value; } set { _Value = value; } } } #endregion #region vlnFormatList, new() public class vlnFormatList : List, ICustomTypeDescriptor where T : vlnFormatItem, new() { private XmlNodeList _XmlNodeList=null; internal XmlNodeList XmlNodeList { get { return _XmlNodeList; } set { _XmlNodeList = value; foreach (XmlNode xn in _XmlNodeList) { T tt = new T(); tt.XmlNode = xn; Add(tt); } } } public vlnFormatList(XmlNodeList xmlNodeList) { if (xmlNodeList == null) return; XmlNodeList = xmlNodeList; } public vlnFormatList() { } private IFormatOrFormatInfo _MyFormat; public IFormatOrFormatInfo MyFormat { get { if (_MyFormat == null) { XmlNode node = _XmlNodeList[0]; // Get the first node in a list vlnFormatDocument doc = null; if (node != null) doc = (node.OwnerDocument) as vlnFormatDocument; // Get the owner document as a vlnFormatDocument if (doc != null) _MyFormat = doc.MyFormat; // Get the Format associated with the vlnFormatDocument } return _MyFormat; } set { _MyFormat = value; } } #region ICustomTypeDescriptor public String GetClassName() { return TypeDescriptor.GetClassName(this, true); } public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(this, true); } public String GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } public TypeConverter GetConverter() { return TypeDescriptor.GetConverter(this, true); } public EventDescriptor GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } public PropertyDescriptor GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); } public object GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); } public EventDescriptorCollection GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); } public EventDescriptorCollection GetEvents() { return TypeDescriptor.GetEvents(this, true); } public object GetPropertyOwner(PropertyDescriptor pd) { return this; } public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { return GetProperties(); } public virtual PropertyDescriptorCollection GetProperties() { // Create a collection object to hold property descriptors PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null); // Iterate the list int i = 0; for (i = 0; i < this.Count; i++) { // Create a property descriptor for the item and add to the property descriptor collection pds.Add(new vlnPropertyDescriptor, T>(this, i)); } // return the property descriptor collection return pds; } #endregion } #endregion #region vlnIndexedFormatList public class vlnIndexedFormatList : vlnFormatList, ICustomTypeDescriptor where T : vlnFormatItem,IVlnIndexedFormatItem, new() { public vlnIndexedFormatList(XmlNodeList xmlNodeList,IFormatOrFormatInfo myFormat) : base(xmlNodeList) { MyFormat = myFormat; } public vlnIndexedFormatList() : base() { } public virtual vlnIndexedFormatList InheritedList { get { return null; } } public new T this[int index] { get { foreach (T tmp in this) { if (tmp.Index == index) return tmp; } vlnIndexedFormatList ttlParent = InheritedList; //Check Inherited Value if (ttlParent != null) return ttlParent[index]; return null; // None found - Can I find it in another format? return null; } } public int MaxIndex { get { int max = base.Count; foreach (T tmp in this) { if (tmp.Index >= max) max = ((int)tmp.Index) + 1; } vlnIndexedFormatList parent = InheritedList; //Check Inherited Value if (parent != null) { int max2 = parent.MaxIndex; if (max2 > max) return max2; } return max; } } public int MaxIndexNoInherit { get { int max = base.Count; foreach (T tmp in this) { if (tmp.Index >= max) max = ((int)tmp.Index) + 1; } return max; } } #region ICustomTypeDescriptor public String GetClassName() { return TypeDescriptor.GetClassName(this, true); } public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(this, true); } public String GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } public TypeConverter GetConverter() { return TypeDescriptor.GetConverter(this, true); } public EventDescriptor GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } public PropertyDescriptor GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); } public object GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); } public EventDescriptorCollection GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); } public EventDescriptorCollection GetEvents() { return TypeDescriptor.GetEvents(this, true); } public object GetPropertyOwner(PropertyDescriptor pd) { return this; } public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { return GetProperties(); } public virtual PropertyDescriptorCollection GetProperties() { // Create a collection object to hold property descriptors PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null); // Iterate the list int i = 0; for (i = 0; i < this.Count; i++) { // Create a property descriptor for the item and add to the property descriptor collection pds.Add(new vlnPropertyDescriptor, T>(this, i)); } // return the property descriptor collection return pds; } #endregion } #endregion #region vlnNamedFormatList public class vlnNamedFormatList : vlnFormatList, ICustomTypeDescriptor where T : vlnFormatItem, IVlnNamedFormatItem, new() { public vlnNamedFormatList(XmlNodeList xmlNodeList, IFormatOrFormatInfo myFormat) : base(xmlNodeList) { MyFormat = myFormat; } public vlnNamedFormatList() : base() { } public virtual vlnNamedFormatList InheritedList { get { return null; } } public new T this[string name] { get { foreach (T tmp in this) { if (tmp.Name == name) return tmp; } vlnNamedFormatList ttlParent = InheritedList; //Check Inherited Value if (ttlParent != null) return ttlParent[name]; return null; // None found - Can I find it in another format? return null; } } public new T this[int index] { get { if(base.Count > index) return base[index]; vlnNamedFormatList ttlParent = InheritedList; //Check Inherited Value if (ttlParent != null) return ttlParent[index]; return null; // None found - Can I find it in another format? return null; } } public new int Count { get { return base.Count; } } #region ICustomTypeDescriptor public String GetClassName() { return TypeDescriptor.GetClassName(this, true); } public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(this, true); } public String GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } public TypeConverter GetConverter() { return TypeDescriptor.GetConverter(this, true); } public EventDescriptor GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } public PropertyDescriptor GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(this, true); } public object GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); } public EventDescriptorCollection GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); } public EventDescriptorCollection GetEvents() { return TypeDescriptor.GetEvents(this, true); } public object GetPropertyOwner(PropertyDescriptor pd) { return this; } public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { return GetProperties(); } public virtual PropertyDescriptorCollection GetProperties() { // Create a collection object to hold property descriptors PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null); // Iterate the list int i = 0; for (i = 0; i < this.Count; i++) { // Create a property descriptor for the item and add to the property descriptor collection pds.Add(new vlnPropertyDescriptor, T>(this, i)); } // return the property descriptor collection return pds; } #endregion } #endregion #region vlnListConverter internal class vlnListConverter : ExpandableObjectConverter where T : vlnFormatList where C : vlnFormatItem, new() { private string Plural(string name) { if (name.EndsWith("y")) return name.Substring(0, name.Length - 1) + "ies"; if (name.EndsWith("ss")) return name + "es"; else return name + "s"; } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destType) { if (destType == typeof(string) && value is T) { // Return department and department role separated by comma. return ((T)value).Count.ToString() + " " + (((T)value).Count == 1 ? typeof(C).Name : Plural(typeof(C).Name)); } return base.ConvertTo(context, culture, value, destType); } } #endregion #region vlnIndexedListConverter internal class vlnIndexedListConverter : ExpandableObjectConverter where T : vlnIndexedFormatList where C : vlnFormatItem,IVlnIndexedFormatItem, new() { private string Plural(string name) { if (name.EndsWith("y")) return name.Substring(0, name.Length - 1) + "ies"; if (name.EndsWith("ss")) return name + "es"; if (name.EndsWith("x")) return name + "es"; else return name + "s"; } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destType) { if (destType == typeof(string) && value is T) { // Return department and department role separated by comma. return ((T)value).MaxIndex.ToString() + " " + (((T)value).MaxIndex == 1 ? typeof(C).Name : Plural(typeof(C).Name)); } return base.ConvertTo(context, culture, value, destType); } } #endregion #region vlnPropertyDescriptor public class vlnPropertyDescriptor : PropertyDescriptor where T : vlnFormatList where C : vlnFormatItem, new() { protected C _Item = null; public vlnPropertyDescriptor(T itemList, int index) : base("#" + index.ToString(), null) { _Item = itemList[index]; } public override bool CanResetValue(object component) { return true; } public override Type ComponentType { get { return _Item.GetType(); } } public override object GetValue(object component) { return _Item; } public override bool IsReadOnly { get { return true; } } public override Type PropertyType { get { return _Item.GetType(); } } public override void ResetValue(object component) { ;} public override bool ShouldSerializeValue(object component) { return true; } public override void SetValue(object component, object value) { /*_Item = value*/;} //public override AttributeCollection Attributes //{ get { return new AttributeCollection(null); } } public override string DisplayName { get { return _Item.GetPDDisplayName(); } } public override string Description { get { return _Item.GetPDDescription(); } } public override string Name { get { return _Item.GetPDName(); } } public override string Category { get { return _Item.GetPDCategory(); } } } // Class #endregion }