/// <summary> /// Deserializes the graphtype /// </summary> /// <param name="g">the graphtype which acts as an intermediate storage between XML and the GraphAbstract /// </param> /// <returns></returns> private GraphAbstract Deserialize(GraphType g) { GraphAbstract abs = new GraphAbstract(); abs.Description = g.Description; ShapeBase shape = null, from = null, to = null; NodeType node; DataType dt; Connection con; ParentChildCollection pcs = new ParentChildCollection(); //temporary store for parent-child relations #region Load the nodes for(int k =0; k<g.Nodes.Count;k++) //loop over all serialized nodes { try { #region find out which type of shape needs to be instantiated node = g.Nodes[k] as NodeType; Type shapeType = Type.GetType(node.Type); if (shapeType != null) { object[] args = {this.site}; shape = Activator.CreateInstance(shapeType, args) as ShapeBase; } #endregion #region use the attribs again to reconstruct the props for(int m=0; m<node.Items.Count;m++) //loop over the serialized data { dt = node.Items[m] as DataType; if(dt.Key=="ParentNode") { //forget the parenting, it's done in a separate loop to be sure all shapes are loaded if(dt.Text.Count>0) //could be if the shape is the root pcs.Add(new ParentChild(shape, dt.Text[0].ToString())); else { shape.IsRoot = true; abs.Root = shape; } continue; } foreach (PropertyInfo pi in shape.GetType().GetProperties()) { if (Attribute.IsDefined(pi, typeof(GraphDataAttribute))) { if(pi.Name==dt.Key) { if(pi.GetIndexParameters().Length==0) { if(pi.PropertyType.Equals(typeof(int))) pi.SetValue(shape,Convert.ToInt32(dt.Text[0]),null); else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer pi.SetValue(shape,Color.FromArgb(int.Parse(dt.Text[0].ToString())),null); else if(pi.PropertyType.Equals(typeof(string))) pi.SetValue(shape,(string)(dt.Text[0]),null); else if(pi.PropertyType.Equals(typeof(bool))) pi.SetValue(shape,Convert.ToBoolean(dt.Text[0]),null); else if(pi.PropertyType.Equals(typeof(Guid))) pi.SetValue(shape,new Guid((string) dt.Text[0]),null); } else pi.SetValue(shape,dt.Text,null); break; } } } } #endregion shape.Font = site.Font; shape.Fit(); abs.Shapes.Add(shape); } catch(Exception exc) { Trace.WriteLine(exc.Message); continue; } }//loop over nodes #endregion //now for the edges; //every node has precisely one parent and one connection to it, unless it's the root for(int n=0; n<pcs.Count; n++) { from = pcs[n].ChildShape; to = abs.Shapes[pcs[n].Parent]; con = new Connection(from, to ); abs.Connections.Add(con); con.site = site; if(pcs[n].ChildShape.visible) con.visible = true; from.connection = con; //a lot of crossing...to make life easy really from.parentNode =to; to.childNodes.Add(from); } return abs; }