// 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 void CreateInitialObjects(Column column) { if (FNestingLevel >= FMaxNestingLevel) { return; } FNestingLevel++; PropertyDescriptorCollection properties = GetProperties(column); foreach (PropertyDescriptor prop in properties) { Type type = prop.PropertyType; bool isSimpleProperty = IsSimpleType(type); bool isEnumerable = IsEnumerable(type); Column childColumn = null; if (isEnumerable) { childColumn = new BusinessObjectDataSource(); } else { childColumn = new Column(); } column.Columns.Add(childColumn); childColumn.Name = isEnumerable ? FDictionary.CreateUniqueName(prop.Name) : prop.Name; childColumn.Alias = prop.DisplayName; childColumn.DataType = type; childColumn.PropName = prop.Name; childColumn.PropDescriptor = prop; childColumn.SetBindableControlType(type); childColumn.Enabled = !isEnumerable || FNestingLevel < FMaxNestingLevel; if (!isSimpleProperty) { GetReference(column, childColumn); CreateInitialObjects(childColumn); } } FNestingLevel--; }
private void PRegisterBusinessObject(IEnumerable data, string referenceName, int maxNestingLevel, bool enabled) { dictionary.AddRegisteredItem(data, referenceName); Type dataType = data.GetType(); if (data is BindingSource) { if ((data as BindingSource).DataSource is Type) { dataType = ((data as BindingSource).DataSource as Type); } else { dataType = (data as BindingSource).DataSource.GetType(); } } BusinessObjectConverter converter = new BusinessObjectConverter(dictionary); BusinessObjectDataSource source = FindDataComponent(referenceName) as BusinessObjectDataSource; if (source != null) { source.Reference = data; source.DataType = dataType; converter.UpdateExistingObjects(source, maxNestingLevel); } else { source = new BusinessObjectDataSource(); source.ReferenceName = referenceName; source.Reference = data; source.DataType = dataType; source.Name = CreateUniqueName(referenceName); source.Alias = CreateUniqueAlias(source.Alias); source.Enabled = enabled; dictionary.DataSources.Add(source); converter.CreateInitialObjects(source, maxNestingLevel); AddBaseWithChiledToDictonary(source); } }
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--; }