public abstract class GoXmlSimpleData
public abstract class GoXmlSimpleData
This abstract class does not define any properties, so there will not be any property name conflicts with any properties that you want to define.
The Northwoods.Go.GoMultiTextNode class holds a variable number of items, along with corresponding ports for each item. It would be natural to represent such a node in XML by having a fixed set of attributes corresponding to node properties, and then a collection of nested elements describing each of the items and their ports.
However, the Northwoods.Go.GoMultiTextNode class is not organized such that there is a collection of objects (Northwoods.Go.GoGroups) that are holding an item and its ports. Instead an item has the same Northwoods.Go.GoObject.Parent as the item's port. The items and ports all belong directly to the node in one big collection. So there is no Northwoods.Go.GoObject class representing an "item" for which you could define a GoXmlTransformer.
Instead you can define an auxiliary data class that holds the information about each item. Here's the start of such a definition:
Then one can define a transformer for MultiTextNodeItem
and a transformer for Northwoods.Go.GoMultiTextNode that generates nested child elements for each item and then consumes them by creating the appropriate Northwoods.Go.GoObjects and adding them to the Northwoods.Go.GoMultiTextNode.
However, you can avoid having to implement a transformer class for MultiTextNodeItem
if you inherit from GoXmlSimpleData and define real .NET properties for each property you want to store so that you can use GoXmlBindingTransformer.
You can then define a GoXmlBindingTransformer for MultiTextNodeItem
. The number of attributes/properties that you decide to read/write is dependent on your particular application's needs, of course. But one possibility is something like:
The GoXmlBindingTransformer for Northwoods.Go.GoMultiTextNode might be implemented as:
An example of the resulting XML could be:
internal class MultiTextNodeItem { // this way requires implementing a transformer subclass public GoObject Item; public GoObject LeftPort; public GoObject RightPort; }
internal class MultiTextNodeItem : GoXmlSimpleData { // no transformer subclass needed public MultiTextNodeItem() { } public GoObject Item { get { return (GoObject)Get("Item"); } set { Set("Item", value); } } public GoObject LeftPort { get { return (GoObject)Get("LeftPort"); } set { Set("LeftPort", value); } } public GoObject RightPort { get { return (GoObject)Get("RightPort"); } set { Set("RightPort", value); } } }
MultiTextNodeItem item = new MultiTextNodeItem(); // represents an item as if it were a single GoObject GoMultiTextNode mtn = new GoMultiTextNode(); item.Item = mtn.CreateText("", 0); item.LeftPort = mtn.CreatePort(true, 0); item.RightPort = mtn.CreatePort(false, 0); GoXmlBindingTransformer st = new GoXmlBindingTransformer("item", item); st.AddBinding("text", "Item.Text"); st.AddBinding("sel", "Item.Selectable"); st.AddBinding("bold", "Item.Bold"); st.AddBinding("width", "Item.Width"); st.AddBinding("wrap", "Item.WrappingWidth"); st.AddBinding("LeftPort", "LeftPort", GoXmlBindingFlags.DefinesShared); st.AddBinding("RightPort", "RightPort", GoXmlBindingFlags.DefinesShared); readerorwriter.AddTransformer(st);
internal class SimpleGoMultiTextNodeTransformer : GoXmlBindingTransformer { public SimpleGoMultiTextNodeTransformer(String eltname, GoMultiTextNode obj) : base(eltname, obj) { this.IdAttributeUsedForSharedObjects = true; // all nodes get an "id" attribute this.BodyConsumesChildElements = true; // make sure ConsumeChild gets called AddBinding("ItemWidth"); // attribute name is same as property name AddBinding("back", "Brush.Color"); AddBinding("loc", "ListGroup.Location"); AddBinding("TopPort", "TopPort", GoXmlBindingFlags.DefinesShared); // write out reference for and to the TopPort AddBinding("BottomPort", "BottomPort", GoXmlBindingFlags.DefinesShared); // ibid for BottomPort } public override void GenerateBody(Object obj) { base.GenerateBody(obj); GoMultiTextNode mtn = (GoMultiTextNode)obj; for (int i = 0; i < mtn.ItemCount; i++) { MultiTextNodeItem dummy = new MultiTextNodeItem(); dummy.Item = mtn.GetItem(i); dummy.LeftPort = mtn.GetLeftPort(i); dummy.RightPort = mtn.GetRightPort(i); this.Writer.GenerateObject(dummy); } } public override void ConsumeChild(Object parent, Object child) { base.ConsumeChild(parent, child); GoMultiTextNode mtn = (GoMultiTextNode)parent; MultiTextNodeItem item = child as MultiTextNodeItem; if (item != null) { // because MultiTextNodeItem inherits from GoXmlSimpleData, // the GoObject properties of item will have been copied for you already, // so you can just add them to your group mtn.AddItem(item.Item, item.LeftPort, item.RightPort); } } }
<GoMultiTextNode id="30" ItemWidth="100" back="-18751" loc="36.5 379" TopPort="73" BottomPort="74"> <item text="first" sel="false" bold="true" width="100" wrap="100" LeftPort="75" RightPort="76" /> <item text="second" sel="true" bold="false" width="100" wrap="100" LeftPort="77" RightPort="78" /> <item text="third" sel="true" bold="true" width="100" wrap="100" LeftPort="79" RightPort="80" /> </GoMultiTextNode>