// discovers the tree node structure (create subnodes) private void DiscoverNode(TreeNode node) { Column column = node.Tag as Column; // create tree nodes based on info from business object. Use existing Column only to // correct the checked & text properties. This will guarantee that we have tree // that match actual schema PropertyDescriptorCollection properties = GetProperties(column); if (properties.Count > 0) { foreach (PropertyDescriptor prop in properties) { Type type = prop.PropertyType; bool isSimpleProperty = IsSimpleType(type); bool isEnumerable = IsEnumerable(type); // find existing column Column childColumn = column.FindByPropName(prop.Name); // column not found, create new one with default settings if (childColumn == null) { if (isEnumerable) { childColumn = new BusinessObjectDataSource(); } else { childColumn = new Column(); } childColumn.Name = prop.Name; childColumn.Alias = prop.DisplayName; childColumn.SetBindableControlType(type); // enable column if it is simple property (such as int), or it is class-type // property that will not lead to loop. The latter is needed to enable all nested // properties automatically childColumn.Enabled = isSimpleProperty || (!isEnumerable && !IsLoop(node, type)); } // update column's DataType - the schema may be changed childColumn.DataType = type; childColumn.PropName = prop.Name; childColumn.PropDescriptor = prop; if (!isSimpleProperty) { GetReference(column, childColumn); } AddNode(node.Nodes, childColumn); } } else if (IsEnumerable(column.DataType)) { Column childColumn = CreateListValueColumn(column); AddNode(node.Nodes, childColumn); } }
private Column CreateListValueColumn(Column column) { Type itemType = ListBindingHelper.GetListItemType(column.DataType); // find existing column Column childColumn = column.FindByPropName("Value"); // column not found, create new one with default settings if (childColumn == null) { childColumn = new Column(); childColumn.Name = "Value"; childColumn.Enabled = IsSimpleType(itemType); childColumn.SetBindableControlType(itemType); } childColumn.DataType = itemType; childColumn.PropName = "Value"; childColumn.PropDescriptor = null; return(childColumn); }
private void UpdateExistingObjects(Column column) { FNestingLevel++; // reset property descriptors to determine later which columns are outdated foreach (Column c in column.Columns) { c.PropDescriptor = null; } PropertyDescriptorCollection properties = GetProperties(column); if (properties.Count > 0) { foreach (PropertyDescriptor prop in properties) { Type type = prop.PropertyType; bool isSimpleProperty = IsSimpleType(type); bool isEnumerable = IsEnumerable(type); // find existing column Column childColumn = column.FindByPropName(prop.Name); // column not found, create new one if (childColumn == null) { if (isEnumerable) { childColumn = new BusinessObjectDataSource(); } else { childColumn = new Column(); } column.Columns.Add(childColumn); if (isEnumerable) { FNameCreator.CreateUniqueName(childColumn); } else { childColumn.Name = prop.Name; } childColumn.Alias = prop.DisplayName; childColumn.SetBindableControlType(type); // enable column if it is simple property, or max nesting level is not reached childColumn.Enabled = isSimpleProperty || FNestingLevel < FMaxNestingLevel; } // update column's prop data - the schema may be changed childColumn.DataType = prop.PropertyType; childColumn.PropName = prop.Name; childColumn.PropDescriptor = prop; if (childColumn.Enabled && !isSimpleProperty) { GetReference(column, childColumn); UpdateExistingObjects(childColumn); } } } else if (IsEnumerable(column.DataType)) { CreateListValueColumn(column); } // remove non-existent columns for (int i = 0; i < column.Columns.Count; i++) { Column c = column.Columns[i]; // delete columns with empty descriptors, except the "Value" columns if (c.PropDescriptor == null && c.PropName != "Value") { column.Columns.RemoveAt(i); i--; } } FNestingLevel--; }