Trouble doing a drag and drop

Hi,

We are GO customers and we have version 2.3.1 of goDiagram. In our application we programmatically create GoSubGraph on a goview on a panel if user does a dorubberbanding type marquee action.
Then the user collapses it and tries to drag and drop it into another panel with another go view on it. I have some state information stored as the user object of this gosubgraph. BUT as soon as I try to drag and drop this goSubGraph into the next panel the cursor turns to nodrop type cursor (the circle with a crossed line on it). It seems to work occassionally then it stops working. I have all the state objects implement ICloneable.
Please help.

First, make sure GoView.CanInsertObjects() is true for the destination GoView. (Check that no one turns off the AllowInsert property.)

Second, check that there isn't any Control.DragOver (or DragEnter) event handler that is setting the DragEventArgs.Effect to disallow a drop.
Third, is there an override of GoView.DoExternalDrag that is setting the DragEventArgs.Effect property?

I checked the 3 aspectsCry

I turned on the allowinsert property for the source and destination goviews.
IN all situations the dragdropeffects is set to copy or all.
there is no override of GoView.DoExternalDrag that is setting the DragEventArgs.Effect property.
One thing interesting is it the drag drop copy works in some cases(cases where I have programmatically created the source subgraphs without user initiated dorubberbanding) and it does not work in the user initiated sub graph creation cases.
In the cases it works the my subclass (of goSubgraph) cancopy and copyObject overrides are getting called. But in cases where it does not work, these overrides are not getting called.
see my derived subgraph below
using System; using Northwoods.Go; using HMS.Model; using System.Windows.Forms; using HMS.ConfigurationManagement.ComponentConfiguration; using System.Drawing; using System.Drawing.Drawing2D; namespace HMS.Presentation { /// /// Summary description for HmsSubGraph. /// [Serializable] public class HmsSubGraph : GoSubGraph { public GoRectangle fillRectangle; SizeF marginSize = new SizeF( 20, 20 ); float[] customDashPattern = new float[] {9,2}; public static bool eventBypass = true; public SizeF preferredSize; private string instanceName; private string unsavedInstanceName; public AtomNode atomNode; #region Constructors public HmsSubGraph( String typeName, String instanceName, Component userObject, PointF location, SizeF size) : base() { this.InstanceName = instanceName; this.preferredSize = size; this.Location= location; Pen pen = new Pen(Color.FromArgb( 0,0,0 ), 1 ); this.BorderPen = pen; this.Collapsible = true; this.Movable = true; this.Selectable = true; this.Handle.Position = new System.Drawing.PointF(this.Position.X-4, this.Position.Y-4); this.PickableBackground = true; this.addMargin(); // Create the CollapsedObject for the HmsSubGraph... atomNode = new AtomNode( 7, typeName, instanceName, userObject ); //atomNode.UserObject = userObject; this.UserObject = userObject; this.CollapsedObject = atomNode; atomNode.Selectable = false; //////////////////////////////////////////////////////////////////

this.Label.AddObserver(this);
this.Label.Alignment = GoText.TopCenter;
this.Label.StringTrimming = StringTrimming.EllipsisCharacter;
this.Label.AutoResizes = false;
this.Label.Clipping = true;
this.Label.Multiline = false;
this.Label.Wrapping = false;
this.Label.Width = 150;
this.Label.Editable = false;
this.Label.Copyable = true;
if ( ! userObject.IsInstantiated )
{
layoutAuthoringSubgraph();
}
this.Copyable = true;

setAppearance();
this.LayoutPort();
}
#endregion

#region Properties
public string InstanceName
{
get
{
return instanceName;
}
set
{
instanceName = value;
unsavedInstanceName = "" + value;
}
}
public string UnsavedInstanceName
{
get
{
return unsavedInstanceName;
}
}
#endregion
#region Methods
public void setAppearance()
{
if ( ((Component)this.UserObject).IsInstantiated )
{
this.BorderPen.DashStyle = DashStyle.Solid;
}
else
{
this.BorderPen.DashStyle = DashStyle.Custom;
this.BorderPen.DashPattern = customDashPattern;
}
if ( ((Component)this.UserObject).IsSaved )
{
this.Label.Text = this.instanceName;
}
else
{
this.Label.Text = this.unsavedInstanceName;
}
this.atomNode.setAppearance( Color.Empty, this.BorderPen.DashStyle );
}
private void layoutAuthoringSubgraph()
{
this.fillRectangle = new GoRectangle();
this.fillRectangle.Size =
new SizeF( preferredSize.Width - (marginSize.Width
2),
preferredSize.Height - this.Label.Height - (marginSize.Height2) );
this.fillRectangle.Selectable = false;
this.fillRectangle.Visible = false;
// These location offsets are a function of the label size…
PointF loc = new PointF(Location.X-40, Location.Y+80);
this.fillRectangle.Location = loc;
this.fillRectangle.Copyable = true;
this.addMargin();
this.Add(this.fillRectangle);
}
public void addMargin()
{
this.TopLeftMargin = this.marginSize;
this.BottomRightMargin = this.marginSize;
}
public override void Collapse()
{
base.Collapse ();
this.Handle.Position = new System.Drawing.PointF(this.Position.X+4, this.Position.Y+4);
PointF loc = new PointF( this.Location.X - 4, this.Location.Y - 4 );
this.Position = loc;
this.Label.Visible = false;
}
public override void Expand()
{
base.Expand ();
this.LayoutPort();
this.Label.Visible = true;
if ( ! ((Component)UserObject).IsInstantiated )
{
this.fillRectangle.Visible = false;
}
}
public override void DoResize(GoView view, RectangleF origRect, PointF newPoint, int whichHandle, GoInputState evttype, SizeF min, SizeF max)
{
RectangleF newRect = ComputeResize(origRect, newPoint, whichHandle, min, max, true);
if ( evttype == GoInputState.Finish )
{
this.fillRectangle.Width = newRect.Width - marginSize.Width
2;
this.fillRectangle.Height = newRect.Height - this.Label.Height - marginSize.Height*2;
PointF location =
new PointF( newRect.Location.X + marginSize.Width,
newRect.Location.Y + this.Label.Height + marginSize.Height );
this.fillRectangle.Location = location;
this.fillRectangle.Visible = false;
}
}
public override bool CanCopy()
{
bool retVal = base.CanCopy ();
return retVal;
}
public override GoObject CopyObject(GoCopyDictionary env)
{
return base.CopyObject (env);
}

///


/// this method is overloaded when components are created during authoring. It is important
/// to register the parent child relationships of the component objects during this action.
/// this override performs just that.
///

///
///
///
public override IGoCollection AddCollection(IGoCollection coll, bool reparentLinks)
{
Component thisComponent = (Component)this.UserObject;
Component childComponent = null;
foreach (GoObject childComponentView in coll)
{
if(childComponentView is HmsSubGraph)
{
childComponent = (Component)((HmsSubGraph)childComponentView).UserObject;
}
if(childComponentView is AtomNode)
{
childComponent = (Component)((AtomNode)childComponentView).UserObject;
}
thisComponent.addChild(childComponent);

}
return base.AddCollection (coll, reparentLinks);
}
public override bool OnContextClick( GoInputEventArgs evt, GoView view )
{
/** If a menu exists for a clicked component, display it.
/
GoContextMenu menu = ((Component)this.UserObject).getMenu( view );
if ( menu != null )
{
menu.Show( view, view.PointToClient(Control.MousePosition ));
}
return true;
}
protected override void OnObservedChanged(GoObject observed, int subhint, int oldI, object oldVal, RectangleF oldRect, int newI, object newVal, RectangleF newRect)
{
base.OnObservedChanged (observed, subhint, oldI, oldVal, oldRect, newI, newVal, newRect);
switch ( subhint )
{
case GoText.ChangedText:
atomNode.InstanceNameText.Text = newVal.ToString();
break;
}
}


#endregion
#region Events
#endregion
}
}

see my code that creates this subgraph below
public override bool execute() { XmlNode emptyNode = null; this.view.StartTransaction(); // this.component = new Component(emptyNode, model); // this.component.IsInstantiated = isInstantiated; // // component.createDisplayableObject(view, location, height, width); // this.model.addComponentToModel(component); ComponentFactory factory = ComponentFactory.getFactory("Component"); this.component = factory.createComponent(emptyNode, this.model); GoSubGraph goObj = (GoSubGraph)component.createDisplayableObject(view, location, height, width);;

this.view.FinishTransaction(component.InstanceName);
Console.Out.WriteLine(“component added”);
return true;
}

public virtual GoObject createDisplayableObject(GoView goView, PointF location, float height, float width) { string instanceNameString = null; string typeNameString = null; if ( this.InstanceName == null || this.InstanceName == String.Empty ) { instanceNameString = "[new]"; } else { instanceNameString = this.InstanceName; } if ( this.TypeName == null || this.TypeName == String.Empty ) { typeNameString = "[type]"; } else { typeNameString = this.TypeName; } HmsSubGraph = new HmsSubGraph(typeNameString, instanceNameString, this, location, new SizeF(width, height)); HmsSubGraph.AddCollection(goView.Selection, false); goView.Document.Add(HmsSubGraph); HmsSubGraph.Collapse(); HmsSubGraph.Expand(); if ( ! this.isInstantiated ) { HmsSubGraph.Resizable = true; HmsSubGraph.Selectable = true; } return this.goObject; }

I’m sorry, but I can’t read what you posted.
So it sounds like your code that constructs a subgraph from a collection of objects isn’t doing the right things.

Are you able to copy the objects in your document when the user has made a subgraph? You could try this quickly by just calling GoDocument.Copy(), and see if there are any exceptions.
Yes. I'am able to do the following after a user creates a my hmssubgraph
GoObject[] objects = new GoObject[100]; this.view.Document.CopyTo(objects, 0);
there are no exceptions.Cry
but a drag and drop of the created subgraph does not work across views.
chida
From my preevious posting.
...
One thing interesting is it the drag drop copy works in some cases(cases where I have programmatically created the source subgraphs without user initiated dorubberbanding) and it does not work in the user initiated sub graph creation cases.
In the cases it works the my subclass (of goSubgraph) cancopy and copyObject , copychildren overrides are getting called. But in cases where it does not work, these overrides are not getting called.

Ah, that’s not what I meant. You’re just filling in an array of references to GoObjects.

But it's not your fault you misunderstood me. It turns out that we added the GoDocument.Copy method after version 2.3, so you couldn't call it in your version.
Assuming "olddoc" is your current document with a user-constructed subgraph, try this instead:
GoDocument newdoc = new GoDocument(); // or whatever class you have inherited from GoDocument...
newdoc.MergeLayersFrom(olddoc);
newdoc.CopyFromCollection(olddoc);
It wouldn't hurt to see if you can replace your GoView.Document with this new document, and make sure everything works.
That code above doesn't exactly make a copy of your old document, but it's probably good enough for these purposes.
Basically I'm asking you to test whether all your GoObjects can be successfully copied. Perhaps you have added some fields/properties that when copied shares references to your data structures that really shouldn't be shared.
I had the following
create and add the subgraph to the document.
I added the three lines you said
newdoc.MergeLayersFrom(olddoc);
newdoc.CopyFromCollection(olddoc);
followed by replacing the old doc with the new doc
this.view.Document = newdoc;
This fixed my copying issues now I'm able to copy the created subgraph from this view to another view. But I'm thinking this is not the solution I need. like I expected this poses a slew of other issues including my undo's don't work(even if I tried to copy my undo manager as well).
What I don't understand is why subgroups become copyable when I copythem into a new document and swap the document in my case?

Hmmm. That wasn’t the result I expected – I was anticipating that during the copying of the document there would be an exception that you could track down.

I was just suggesting this kind of copying operation to track down the problem, not to work around it.
Just to clarify -- the document you copied had a user-created subgraph in it? It was in precisely the same situation where dragging would not work, right?
In looking at parts of the code, that you posted above, I'm struck by the reference to a Component in the UserObject (aka "Tag") property. I'm suspicious that this won't work, because the Component is probably not serializable.
Could you try a copy-and-paste? I bet that won't work. Even if it doesn't fail due to an exception (that Windows Forms handles silently), I bet it won't result in the data structures that you want.

Ok. that makes sense. When I set the user object to null it seems to work.

But I do have these kinds of subgraphs(with components as the user object)created programmatically(not due to a user gesture) in a goview on a panel. I'm able to drag and drop them! Only the subgraphs I'm creating using the rubber banding have this issue.
I tried making my component object serializable. Did not seem to help.
Another interesting thing is this drag and drop works whenever I add some new code into some file (particularly my subgraph or my component etc )and build my project again! But the next time I run the project it would not do the drag and drop. I don't know if it rings any bells.
Any suggestions

Regarding serialization, you can test it using the code I suggest in http://www.nwoods.com/forum/forum_posts.asp?TID=880.

You'll need to figure out how one programmatically created subgraph (with your initialization) is different the other one (created by your code due to user request). I suggest simplifying it as much as you can. Remember that all the regular GoDiagram stuff works fine. It's just your extensions, either fields that you have added or your use of UserObject, and perhaps any method overrides (or lack of CopyObject override?), that is probably causing problems with improperly shared or initialized data or with non-serializable data.