public ServerObjectParsingObject(Type type, Hashtable attributes, string tagid, ParsingObject parent)
: base(tagid, parent)
{
//create the object
if (type.GetInterface ("System.ComponentModel.IComponent") != null)
//note: this automatically adds to parent's container, as some controls
//need to be sited e.g. if they use site dictionaries
//TODO: should this action be passed up the tree so controls can intercept?
obj = base.DesignerHost.CreateComponent (type, attributes["ID"] as string);
else
obj = Activator.CreateInstance (type);
//and populate it from the attributes
pdc = TypeDescriptor.GetProperties (obj);
foreach (DictionaryEntry de in attributes) {
if (0 == string.Compare((string)de.Key, "runat"))
continue;
if (0 == string.Compare((string)de.Key, "ID"))
continue;
//use the dash subproperty syntax
string[] str = ((string)de.Key).Split ('-');
PropertyDescriptor pd = pdc.Find (str[0], true);
//if property not found, try events
if (str.Length == 1 && pd == null && CultureInfo.InvariantCulture.CompareInfo.IsPrefix (str[0], "On")) {
IEventBindingService iebs = (IEventBindingService) DesignerHost.GetService (typeof (IEventBindingService));
if (iebs == null)
throw new Exception ("Could not obtain IEventBindingService from host");
EventDescriptorCollection edc = TypeDescriptor.GetEvents (obj);
EventDescriptor e = edc.Find (str[0].Remove(0,2), true);
if (e != null)
pd = iebs.GetEventProperty(e);
else
throw new Exception ("Could not find event " + str[0].Remove(0,2));
}
object loopObj = obj;
for (int i = 0; i < str.Length; i++ )
{
if (pd == null)
throw new Exception ("Could not find property " + (string)de.Key);
Console.WriteLine (pd.Converter.ToString() + " " + pd.Name);
if (i == str.Length - 1) {
pd.SetValue (obj, pd.Converter.ConvertFromString ((string) de.Value));
break;
}
loopObj = pd.GetValue (loopObj);
pd = TypeDescriptor.GetProperties (loopObj).Find (str[0], true);
}
}
parseAtt = TypeDescriptor.GetAttributes (obj)[typeof(ParseChildrenAttribute )] as ParseChildrenAttribute;
//FIXME: fix this in MCS classlib
if (parseAtt.DefaultProperty.Length == 0)
parseAtt = null;
//work out how we're trying to parse the children
if (parseAtt != null) {
if (parseAtt.DefaultProperty != null) {
PropertyDescriptor pd = pdc[parseAtt.DefaultProperty];
if (pd == null)
throw new Exception ("Default property does not exist");
if (pd.PropertyType.GetInterface("System.Collections.IList") == (typeof(IList)))
mode = ParseChildrenMode.DefaultCollectionProperty;
else
mode = ParseChildrenMode.DefaultProperty;
}
else if (parseAtt.ChildrenAsProperties)
mode = ParseChildrenMode.Properties;
else
mode = ParseChildrenMode.Controls;
}
else {
//FIXME: these are actually persistence hints, but ParseChildrenAttribute doesn't always exist.
//FIXME: logic would be dodgy with bad input
parseAtt = ParseChildrenAttribute.Default;
mode = ParseChildrenMode.Controls;
foreach (PropertyDescriptor pd in pdc) {
PersistenceModeAttribute modeAttrib = pd.Attributes[typeof(PersistenceModeAttribute)] as PersistenceModeAttribute;
if (modeAttrib == null) return;
switch (modeAttrib.Mode) {
case PersistenceMode.Attribute:
continue;
case PersistenceMode.EncodedInnerDefaultProperty:
parseAtt.DefaultProperty = pd.Name;
mode = ParseChildrenMode.DefaultEncodedProperty;
break;
case PersistenceMode.InnerDefaultProperty:
parseAtt.DefaultProperty = pd.Name;
if (pd.PropertyType.GetInterface("System.Collections.IList") == (typeof(IList)))
mode = ParseChildrenMode.DefaultCollectionProperty;
else
mode = ParseChildrenMode.DefaultProperty;
break;
case PersistenceMode.InnerProperty:
mode = ParseChildrenMode.Properties;
break;
}
}
}
}