Mapping

I am trying to create an environment similar to the Biztalk Mapping Environment, which has two node views on either side of the main View. It can be seen here:

http://www.microsoft.com/biztalk/images/img_BizTalkMapper.gi f
http://www.peirsontopeirson.com/one_CD/CD_Master/images/mapp er.gif

How might I accomplish this with GoDiagram? I tried setting up 3 GoViews, but it didn’t like that, it would just copy objects when I dragged them back and forth, and the links couldn’t go between different GoViews. Maybe there is a way to set up different regions where certain objects are or aren’t permitted, with different color backgrounds?

Why not use two TreeViews in a GoView?
Here’s one way to put a System.Windows.Forms.TreeView in a GoView, using a GoControl:
http://www.nwoods.com/forum/uploads/TreeViewNode.cs
That code doesn’t do anything to manage a bunch of GoPorts that you’ll want positioned where the System.Windows.Forms.TreeNodes are. You’ll want to handle expand and collapse, of course, and also drag-and-drop to start drawing a new link from inside a TreeView.

I think I can handle the collapse/expand stuff, but what would you suggest to do this?

Here is what I have so far:

Dim tvnSource As TreeViewNode.TreeViewNodeControl
Dim tvnDestination As TreeViewNode.TreeViewNodeControl

Dim stndBorderBuffer As Integer = 10

Private Sub Mapper_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    With myView

     &nbs p;  .Border3DStyle = Border3DStyle.Flat

     &nbs p;  .BackColor = Color.Silver

     &nbs p;  .GridCellSize = New SizeF(22, 22)

     &nbs p;  .GridColor = Color.White

     &nbs p;  .GridOrigin = New PointF(0, -1)

     &nbs p;  .GridPenDashStyle = Drawing2D.DashStyle.Dash

     &nbs p;  .GridPenWidth = 1

     &nbs p;  .GridSnapDrag = Northwoods.Go.GoViewSnapStyle.Jump

     &nbs p;  .GridSnapResize = Northwoods.Go.GoViewSnapStyle.Jump

     &nbs p;  .GridStyle = Northwoods.Go.GoViewGridStyle.Line
    End With

    tvnSource = New TreeViewNode.TreeViewNodeControl
    With tvnSource

     &nbs p;  .myControl.Mirrored = False

     &nbs p;  Dim tn As New System.Windows.Forms.TreeNode

     &nbs p;  tn.Text = "Source"

     &nbs p;  tn.Nodes.Add("hello")

     &nbs p;  tn.Nodes.Add("test")

     &nbs p;  With tvnSource.myControl

     &nbs p;      .BackColor = Color.White

     &nbs p;      .BorderStyle = BorderStyle.Fixed3D

     &nbs p;      .ShowPlusMinus = True

     &nbs p;      .ShowRootLines = True

     &nbs p;      .ShowLines = True

     &nbs p;      .Nodes.Add(tn)

     &nbs p;  End With

     &nbs p;  .Shadowed = True

     &nbs p;  .Selectable = False

     &nbs p;  .Movable = False

     &nbs p;  .Height = myView.Height - stndBorderBuffer

     &nbs p;  .Width = 250

     &nbs p;  .Reshapable = False

     &nbs p;  .Position = New PointF(0, 0)
    End With

    tvnDestination = New TreeViewNode.TreeViewNodeControl
    With tvnDestination

     &nbs p;  .myControl.Mirrored = True

     &nbs p;  Dim tn As New System.Windows.Forms.TreeNode

     &nbs p;  tn.Text = "Destination"

     &nbs p;  tn.Nodes.Add("hello")

     &nbs p;  tn.Nodes.Add("test")

     &nbs p;  With tvnDestination.myControl

     &nbs p;      .BackColor = Color.White

     &nbs p;      .BorderStyle = BorderStyle.Fixed3D

     &nbs p;      .ShowPlusMinus = True

     &nbs p;      .ShowRootLines = True

     &nbs p;      .ShowLines = True

     &nbs p;      '.RightToLeft = RightToLeft.Yes

     &nbs p;      .Nodes.Add(tn)

     &nbs p;  End With

     &nbs p;  .Shadowed = True

     &nbs p;  .Selectable = False

     &nbs p;  .Movable = False

     &nbs p;  .Height = myView.Height - stndBorderBuffer

     &nbs p;  .Width = 250

     &nbs p;  .Reshapable = False

     &nbs p; 

.Position = New PointF(myView.Width - 250 - stndBorderBuffer, 0)
End With

    ' enable main view appropriately according to check box options
    myView.AllowLink = True ' = LinkingModeCheckBox.Checked
    myView.AllowEdit = True ' = AllowEditCheckBox.Checked
    ' implement undo/redo support
    myView.Document.UndoManager = New GoUndoManager

    With myView

     &nbs p;  .Border3DStyle = Border3DStyle.Flat

     &nbs p;  '.Document.Add(boNode)

     &nbs p;  .Document.Add(Me.tvnSource)

     &nbs p;  .Document.Add(Me.tvnDestination)
    End With
End Sub

Private Sub Mapper_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize
    Try

     &nbs p;  Me.tvnSource.Height = myView.Height - stndBorderBuffer

     &nbs p;  Me.tvnDestination.Height = myView.Height - stndBorderBuffer

     &nbs p; 

Me.tvnDestination.Position = New PointF(myView.Width - 250 -
stndBorderBuffer, 0)

     &nbs p;  myView.RaiseObjectResized(Me.tvnSource)

     &nbs p;  myView.RaiseObjectResized(Me.tvnDestination)
    Catch
    End Try
End Sub

Private Sub Mapper_SizeChanged(ByVal sender As

Object, ByVal e As System.EventArgs) Handles MyBase.SizeChanged
Try

     &nbs p;  Me.tvnSource.Height = myView.Height - stndBorderBuffer

     &nbs p;  Me.tvnDestination.Height = myView.Height - stndBorderBuffer

     &nbs p; 

Me.tvnDestination.Position = New PointF(myView.Width - 250 -
stndBorderBuffer, 0)

     &nbs p;  myView.RaiseObjectResized(Me.tvnSource)

     &nbs p;  myView.RaiseObjectResized(Me.tvnDestination)
    Catch
    End Try
End Sub

I think you need to implement TreeView.ItemDrag event handlers.
To have the GoView get into the “drawing-a-new-link” mode, you need to do something like:
GoToolLinkingNew tool = (GoToolLinkingNew)goView1.FindMouseTool(typeof(GoToolLinking ));
tool.OriginalStartPort = … the port in the TreeViewNode corresponding to the WinForms TreeNode …;
goView1.Tool = tool; // start the linking tool

I have been running into lots of issues, do you have a working TreeViewNode?

That file I referenced (in our uploads directory) is all we’ve got.
Perhaps someone else has a similar need and can work with you on this.
Eventually we’ll implement this too, but right now we’re busy. In fact, we have almost exactly what you want as a new example, but it’s part of JGo for Swing, not GoDiagram Win. Since most of the work is TreeView-specific, rather than Go-specific, none of that code will translate into WinForms.

Hi Ericasimon and Walter,



I’m going to design a mapper like yours.

If you have any info tell me please.



Thank for ahead



Son

Hi all,
I am interested in a sample about the same subject.
Thank you,
Simone

Hi Walter,
I have some problems as following:
-How to make the ports of the Attributes expand to the right margin when Operations is expanded.
-How to make two ports for the Attributes and the Operations on the left and the right at top instead of middle.
Here is my code
/*

  • Copyright ? Northwoods Software Corporation, 1998-2005. All Rights
  • Reserved.
  • Restricted Rights: Use, duplication, or disclosure by the U.S.
  • Government is subject to restrictions as set forth in subparagraph
  • © (1) (ii) of DFARS 252.227-7013, or in FAR 52.227-19, or in FAR
  • 52.227-14 Alt. III, as applicable.
    */
    using System;
    using System.Collections;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
    using Northwoods.Go;
    namespace Demo1
    {
    [Serializable]
    public class InfoNode8 : GoBoxNode, IGoCollapsible
    {
    private Hashtable m_colLinkList = new Hashtable();
    public InfoNode8()
    {
    this.Port.Style = GoPortStyle.None;
    this.PortBorderMargin = new SizeF(0, 0);
    this.LinkPointsSpread = true;
    LayoutChildren(null);
    }
    public void Initialize()
    {
    this.Text = “Class Node”;
    String star = @“star.gif”;
    String doc = @“doc.gif”;
    this.AttributesLabel.Text = “Attributes”;
    this.Attributes.AddItem(MakeItem(star, “first attribute”),this.Attributes.CreatePort(true,this.Attributes.Count),this.Attributes.CreatePort(false,this.Attributes.Count));
    this.Attributes.AddItem(MakeItem(doc, “second attribute”),this.Attributes.CreatePort(true,this.Attributes.Count),this.Attributes.CreatePort(false,this.Attributes.Count));
    this.Attributes.AddItem(MakeItem(doc, “third attribute”),this.Attributes.CreatePort(true,this.Attributes.Count),this.Attributes.CreatePort(false,this.Attributes.Count));

this.OperationsLabel.Text = “Operations”;
this.Operations.AddItem(MakeItem(star, “first operation”),this.Operations.CreatePort(true,this.Operations.Count),this.Operations.CreatePort(false,this.Operations.Count));
this.Operations.AddItem(MakeItem(doc, “second operation”),this.Operations.CreatePort(true,this.Operations.Count),this.Operations.CreatePort(false,this.Operations.Count));
this.Operations.AddItem(MakeItem(doc, “third operation”),this.Operations.CreatePort(true,this.Operations.Count),this.Operations.CreatePort(false,this.Operations.Count));
this.Operations.AddItem(MakeItem(doc, “fourth operation”),this.Operations.CreatePort(true,this.Operations.Count),this.Operations.CreatePort(false,this.Operations.Count));
this.Operations.AddItem(MakeItem(doc, “fifth operation”),this.Operations.CreatePort(true,this.Operations.Count),this.Operations.CreatePort(false,this.Operations.Count));
GoCollapsibleHandle h = new GoCollapsibleHandle();
h.Position = new PointF(this.Label.Width, 0);
Add(h);
}
public InfoNode8Item MakeItem(String imgname, String s)
{
InfoNode8Item item = new InfoNode8Item();
item.Init(imgname, s);
return item;
}
protected override void OnBoundsChanged(
RectangleF old
)
{
base.OnBoundsChanged(old);
}
private void LayoutPorts()
{
foreach(GoPort port in this.Ports)
{
port.Style =GoPortStyle.Triangle;
port.Brush = null;
if(port is GoBoxPort)
{
port.Visible = false;
port.IsValidTo = false;
port.IsValidFrom = false;
}
}
if(this.MyBody!=null)
{
foreach(GoPort port in this.MyBody.Ports)
{
if (port.ToSpot==GoObject.MiddleBottom||port.ToSpot==GoObject.M iddleTop)
{
port.Visible = false;
port.IsValidTo = false;
port.IsValidFrom = false;
}
else
{
port.SetSpotLocation(port.ToSpot, new PointF(port.Position.X,MyBody.ListGroup[0].Position.Y));
port.Style =GoPortStyle.TriangleMiddleLeft;
port.Brush = null;
}
}
}
}
public override void LayoutChildren(GoObject childchanged)
{
base.LayoutChildren(childchanged);
// position the GoCollapsibleHandle in the top-right spot, minus any rounded corner
GoObject h = this.Last;
if (h != null && this.MyBody != null)
{
h.Position = new PointF(this.MyBody.Left + this.MyBody.Width - h.Width - this.MyBody.Corner.Width,
this.MyBody.Top + this.MyBody.Corner.Height);
}
LayoutPorts();
}
// The Body is a vertical GoMultiTextNode consisting of
// a HeaderSection, an AttributesSection, and an OperationsSection.
// The HeaderSection is itself a GoMultiTextNode containing two text objects,
// the Title and the Description.
// Both the AttributesSection and the OperationsSection are implemented by
// instances of CollapsingItem, defined below.
protected override GoObject CreateBody()
{
GoMultiTextNode lg = new GoMultiTextNode();
lg.Alignment = GoObject.TopLeft;
lg.Selectable = false;
lg.Brush = Brushes.Lavender;
lg.BorderPen = Pens.Black;
lg.LinePen = new Pen(Color.Black, 2);
lg.Spacing = 2;
lg.TopLeftMargin = new SizeF(0, 2);
lg.BottomRightMargin = new SizeF(0, 2);
lg.Corner = new SizeF(4, 4);
GoListGroup header = new GoListGroup();
header.Selectable = false;
GoText title = new GoText();
title.AutoResizes = true;
title.Selectable = false;
header.Add(title);
lg.AddItem(header,lg.CreatePort(true,lg.Count),lg.CreatePort(false,lg.Count));
CollapsingItem atts = new CollapsingItem();
atts.Selectable = false;
lg.AddItem(atts,lg.CreatePort(true,lg.Count),lg.CreatePort(false,lg.Count));
CollapsingItem ops = new CollapsingItem();
ops.Selectable = false;
lg.AddItem(ops,lg.CreatePort(true,lg.Count),lg.CreatePort(false,lg.Count));
//Ensure ports visible
return lg;
}
private GoMultiTextNode MyBody
{
get { return this.Body as GoMultiTextNode; }
}

// access to the header objects
public GoListGroup HeaderSection
{
get { return (GoListGroup)this.MyBody.ListGroup[0]; }
}
public override GoText Label
{
get { return this.HeaderSection[0] as GoText; }
set { this.HeaderSection[0] = value; }
}
// access to the attributes objects
public CollapsingItem AttributesSection
{
get { return (CollapsingItem)this.MyBody.ListGroup[1]; }
}
// access to the attributes label, shown when collapsed
public GoText AttributesLabel
{
get { return this.AttributesSection.Label; }
}
// access to the list of attributes
public GoMultiTextNode Attributes
{
get { return this.AttributesSection.List; }
}
// access to the operations objects
public CollapsingItem OperationsSection
{
get { return (CollapsingItem)this.MyBody.ListGroup[2]; }
}
// access to the operations label, shown when collapsed
public GoText OperationsLabel
{
get { return this.OperationsSection.Label; }
}
// access to the list of operations
public GoMultiTextNode Operations
{
get { return this.OperationsSection.List; }
}
public override RectangleF Bounds
{
get { return base.Bounds; }
set
{
base.Bounds = value;
if (this.MyBody != null)
{
this.MyBody.Brush = new LinearGradientBrush(this.MyBody.Position, new PointF(this.MyBody.Right, this.MyBody.Top),
Color.LightSteelBlue, Color.White);
}
}
}
// implement IGoCollapsible:
public bool Collapsible
{
get { return true; }
set {}
}
public void Collapse()
{
mySavedAttributesSection = this.AttributesSection;
mySavedOperationsSection = this.OperationsSection;
this.MyBody.ListGroup.Remove(mySavedOperationsSection);
this.MyBody.ListGroup.Remove(mySavedAttributesSection);
m_colLinkList.Add(“Attributes”,((GoMultiTextNode)this.MyBody.ListGroup[1]).Links);
m_colLinkList.Add(“Operations”,((GoMultiTextNode)this.MyBody.ListGroup[2]).Links);
}
public void Expand()
{
this.MyBody.ListGroup.Add(mySavedAttributesSection);
this.MyBody.ListGroup.Add(mySavedOperationsSection);
mySavedAttributesSection = null;
mySavedOperationsSection = null;
}
public bool IsExpanded
{
get { return this.MyBody.ListGroup.Count > 1; }
}
private GoObject mySavedAttributesSection = null;
private GoObject mySavedOperationsSection = null;
}

// Each collection of attributes and of operations are held in one of these,
// to support expand and collapse, showing a simple label when collapsed,
// or showing a list of InfoNode8Items when expanded.
[Serializable]
public class CollapsingItem : GoListGroup, IGoCollapsible
{
public CollapsingItem()
{
this.Orientation = Orientation.Vertical;
this.Resizable = false;
this.ResizesRealtime = true;
this.AutoRescales = true;
// Now add a handle that shows as either “+” or “-”, and
// that when clicked results in a call to either Expand() or Collapse().
// The handle is Item[0]
GoCollapsibleHandle h = new GoCollapsibleHandle();
h.Visible = false;
Add(h);
// Collapsed label is Item[1]
CollapsingChildItem t = new CollapsingChildItem();
t.Selectable = false;
Add(t);
// List-group is Item[2]
GoMultiTextNode mySecond = new GoMultiTextNode();
//mySecond.LinePen = Pens.White;
//mySecond.BorderPen = Pens.White;
mySecond.Alignment = GoObject.TopLeft;
mySecond.Selectable = false;
Add(mySecond);
Collapse();
}
public GoText Label
{
get { return ((CollapsingChildItem)this[1]).Label as GoText; }
}
public GoMultiTextNode List
{
get { return this[2] as GoMultiTextNode; }
}
public override void LayoutChildren(GoObject childchanged)
{
base.LayoutChildren(childchanged);
if(this.Count>2)
{
LayoutPorts();
}
}
private void LayoutPorts()
{
if(this.List!=null)
{
foreach(GoPort port in this.List.Ports)
{
if (port.ToSpot==GoObject.MiddleBottom||port.ToSpot==GoObject.M iddleTop)
{
port.Visible = false;
port.IsValidTo = false;
port.IsValidFrom = false;
}
else
{
port.SetSpotLocation(port.ToSpot, new PointF(port.Position.X,List.ListGroup[0].Position.Y));
port.Style =GoPortStyle.TriangleMiddleLeft;
port.Brush = null;
}
}
}
}

public override void Paint(Graphics g, GoView view)
{
if (this.IsExpanded)
{
g.FillRectangle(Brushes.White, this.Bounds);
}
base.Paint(g, view);
}
// pretend a collapsed object is smaller than it really is
protected override RectangleF ComputeBounds()
{
if (this.IsExpanded && this.Count > 2)
return RectangleF.Union(this[0].Bounds, RectangleF.Union(this[1].Bounds, this[2].Bounds));
else if (this.Count > 1)
return RectangleF.Union(this[0].Bounds, this[1].Bounds);
else
return this.Bounds;
}
// implement IGoCollapsible:
public bool Collapsible
{
get { return true; }
set {}
}
public void Collapse()
{
//this.Label.Visible = true;
//this.Label.Printable = true;
this.List.Visible = false;
this.List.Printable = false;
// due to override of ComputeBounds, changing Visible changes Bounds–
// need to re-ComputeBounds and re-layout the parent
this.InvalidBounds = true;
if (this.Parent != null)
{
this.Parent.LayoutChildren(this);
}
}
public void Expand()
{
//this.Label.Visible = false;
//this.Label.Printable = false;
this.List.Visible = true;
this.List.Printable = true;
// due to override of ComputeBounds, changing Visible changes Bounds–
// need to re-ComputeBounds and re-layout the parent
this.InvalidBounds = true;
}
public bool IsExpanded
{
get { return this.Count > 2 && this.List.Visible; }
}
}

[Serializable]
public class CollapsingChildItem : GoListGroup, IGoCollapsible
{
public CollapsingChildItem()
{
this.Orientation = Orientation.Horizontal;
this.Resizable = false;
// Now add a handle that shows as either “+” or “-”, and
// that when clicked results in a call to either Expand() or Collapse().
// The handle is Item[0]
GoCollapsibleHandle h = new GoCollapsibleHandle();
Add(h);
// Collapsed label is Item[1]
GoText t = new GoText();
t.Selectable = false;
Add(t);
}
public GoText Label
{
get { return this[1] as GoText; }
}
public override void Paint(Graphics g, GoView view)
{
if (this.IsExpanded)
{
g.FillRectangle(Brushes.White, this.Bounds);
}
base.Paint(g, view);
}
// pretend a collapsed object is smaller than it really is
protected override RectangleF ComputeBounds()
{
if (this.Count > 1)
return RectangleF.Union(this[0].Bounds, this[1].Bounds);
else
return this.Bounds;
}
// implement IGoCollapsible:
public bool Collapsible
{
get { return true; }
set {}
}
public void Collapse()
{
m_bIsExpanded = false;
if (this.Parent is IGoCollapsible)
((IGoCollapsible)this.Parent).Collapse();
}
public void Expand()
{
m_bIsExpanded = true;
if (this.Parent is IGoCollapsible)
((IGoCollapsible)this.Parent).Expand();
}
public bool IsExpanded
{
get { return m_bIsExpanded; }
}
private bool m_bIsExpanded = false;
}
// Each line (item) of the Attributes or the Operations list is one of these–
// a group consisting of an image and a text.
[Serializable]
public class InfoNode8Item : GoGroup
{
public InfoNode8Item()
{
this.Selectable = true;
this.Deletable = false;
this.DragsNode = true;
}
public void Init(String imgname, String s)
{
GoImage img = new GoImage();
img.Selectable = false;
img.AutoRescales = false;
img.Name = imgname;
img.Size = new SizeF(16, 16);
Add(img);
GoText t = new GoText();
t.Bordered = false;
t.Selectable = false;
t.BackgroundColor = Color.LightBlue;
t.BackgroundOpaqueWhenSelected = true;
t.Text = s;
t.Wrapping = true;
t.WrappingWidth = 400;
Add(t);
}
public override GoObject SelectionObject
{
get
{
if (this.Count >= 2)
return this[1];
else
return this;
}
}
public override void LayoutChildren(GoObject childchanged)
{
if (this.Initializing) return;
if (this.Count >= 2)
{
RectangleF newb = this.Bounds;
GoObject first = this[0];
GoObject second = this[1];
if (first.Height >= second.Height)
{
first.Position = newb.Location;
second.SetSpotLocation(GoObject.MiddleLeft, first, GoObject.MiddleRight);
}
else
{
second.Position = new PointF(newb.X+first.Width, newb.Y);
first.SetSpotLocation(GoObject.MiddleRight, second, GoObject.MiddleLeft);
}
}
}
}
}

I have NOT tried the code in the previous post.
Basically you will need to override LayoutChildren of the GoGroup that is the parent of the objects you want to position.