Пример #1
0
        /// <summary>
        /// Builds a BlockContainer control, populating it with the appropriate controls
        /// based on the supplied XML TDF data.
        /// </summary>
        /// <returns>The BlockContainer that was created.</returns>
        protected BlockContainer BuildStruct(XmlNode node, bool mainBlock)
        {
            int depth = 0;

            // Setup the block container.
            BlockContainer container = new BlockContainer();

            container.LinkedUndoManager = this.undoManager;
            containers.Push(container);

            XmlNodeList valueNodes = node.SelectNodes("*");

            foreach (XmlNode valueNode in valueNodes)
            {
                if (valueNode.Name.ToLower() == "group")
                {
                    // Make sure that this node is a direct child of the Main Struct.
                    // That's the only place that groups are allowed to exist.
                    bool allowGroup = false;
                    if (valueNode.ParentNode.Name.ToLower() == "struct")
                    {
                        if (valueNode.ParentNode.Attributes["name"] != null)
                        {
                            if (valueNode.ParentNode.Attributes["name"].InnerText == mainStructName)
                            {
                                allowGroup = true;
                            }
                        }
                    }
                    if (!allowGroup)
                    {
                        throw new Exception("Unable to create group: Not a direct member of the main struct.");
                    }

                    buildDepth.Push(0);
                    CreateTab(valueNode.Attributes["caption"].InnerText);
                    BlockContainer newContainer = BuildStruct(valueNode, mainBlock);
                    newContainer.DatabindChildrenToBlock(this.tagData);
                    containers.Peek().AddFieldContainer(newContainer);
                    containers.Pop();
                    buildDepth.Pop();
                }
                else if (valueNode.Name.ToLower() == "section")
                {
                    // NOTE: This code is duplicated from the block creation.
                    // A seperate method for building sections would really be ideal, but I don't feel
                    // like going into that right now.
                    IFieldContainer fieldContainer;
                    if (((int)buildDepth.Peek()) < 1)
                    {
                        fieldContainer = new SectionContainer();
                        (fieldContainer as SectionContainer).Title = valueNode.Attributes["caption"].InnerText;
                        if (valueNode.Attributes["description"] != null)
                        {
                            (fieldContainer as SectionContainer).Description = valueNode.Attributes["description"].InnerText;
                        }
                    }
                    else
                    {
                        fieldContainer = new RegionContainer();
                        (fieldContainer as RegionContainer).Caption = valueNode.Attributes["caption"].InnerText;
                    }
                    depth = (int)(buildDepth.Pop());
                    buildDepth.Push(depth + 1);

                    BlockContainer newContainer = BuildStruct(valueNode, mainBlock);
                    newContainer.DatabindChildrenToBlock(this.tagData);
                    fieldContainer.AddFieldContainer(newContainer);
                    containers.Peek().AddFieldContainer(fieldContainer);
                }
                else if (valueNode.Name.ToLower() == "value")
                {
                    string valueName        = valueNode.Attributes["name"].InnerText;
                    Field  fieldControl     = new Field();
                    string valueText        = valueNode.Attributes["type"].InnerText;
                    string fullPropertyName = (mainBlock ? className + "Values." : "") + Types.GlobalMethods.MakePublicName(valueName);

                    if (standardControls.ContainsKey(valueText))
                    {
                        //TODO: Look into adding the types into the hashtable, rather than using reflection.
                        string   controlTypeName  = "TagEditor.Controls." + valueText;
                        Type     fieldControlType = Type.GetType(controlTypeName);
                        Assembly targetAssembly   = Assembly.GetAssembly(fieldControlType);
                        fieldControl = (targetAssembly.CreateInstance(controlTypeName) as Field);
                        fieldControl.Configure(valueNode);
                        if (valueText != "Block")
                        {
                            containers.Peek().AddField(fieldControl);
                        }
                        else
                        {
                            fieldControl = new Block();
                            fieldControl.Configure(valueNode);
                            (fieldControl as Block).Caption = "Select Block:";

                            // At this point, we need to recurse and create the sub control for this block.
                            // Step 1: Locate the proper struct in the document.
                            string  structName = valueNode.Attributes["struct"].InnerText;
                            XmlNode structNode = tagDefinition.SelectSingleNode("//struct[@name='" + structName + "']");

                            IFieldContainer fieldContainer;
                            if (((int)buildDepth.Peek()) < 1)
                            {
                                fieldContainer = new SectionContainer();
                                (fieldContainer as SectionContainer).Title = Utility.CapitalizeWords(fieldControl.Caption);
                                XmlNode descriptionNode = structNode.SelectSingleNode("description");
                                if (descriptionNode != null)
                                {
                                    (fieldContainer as SectionContainer).Description = descriptionNode.InnerText;
                                }
                            }
                            else
                            {
                                fieldContainer = new RegionContainer();
                                (fieldContainer as RegionContainer).Caption = Utility.CapitalizeWords(fieldControl.Caption);
                            }
                            depth = (int)(buildDepth.Pop());
                            buildDepth.Push(depth + 1);

                            // Step 2: Build the BlockContainer and dock it.
                            BlockContainer subBlockContainer = BuildStruct(structNode, false);

                            fieldContainer.AddField(fieldControl);
                            fieldContainer.AddFieldContainer(subBlockContainer);

                            containers.Peek().AddFieldContainer(fieldContainer);
                            subBlockContainer.Refresh();

                            // Step 3: Wire up the BlockChanged event for databinding.
                            (fieldControl as Block).BlockChanged += new Block.BlockChangedHandler(subBlockContainer.DatabindChildrenToBlock);
                            (fieldControl as Block).Initialize();
                        }
                    }
                    else
                    {
                        continue;
                    }
                    fieldControl.BoundPropertyName = fullPropertyName;
                }
            }
            depth = (int)(buildDepth.Pop());
            buildDepth.Push(depth - 1);
            containers.Pop();
            return(container);
        }