Entity not found in repository when moving selected Shapes around

Apr 8, 2013 at 1:47 PM
Hi,

In my Project im adding and deleting shapes from code.

The strange thing is, that i get sometimes an "Entity not found in repository" exception when i hold the left mouse button, mark all shapes and try to move them around.

This mostly happens when i have deleted a shape before.

My first opinion was, that i'm adding or deleting the shapes the wrong way.

This is the code i'm adding and deleting shapes :
//Adding a new Shape
Diagram tmpDiag = projectMain.Repository.GetDiagram("Diag1");
Box newShape = (Box)projectMain.Repository.GetTemplate("MyTremplate").CreateShape();
tmpDiag.Shapes.Add(newShape);
projectMain.Repository.Insert((Shape)newShape , tmpDiag);
projectMain.Repository.Update();

//Deleting Shape
displayMain.DeleteShape(newShape);
projectMain.Repository.Update();
When i single mark each shape by holding the "strg"-key everthing is working fine.

Are there some commands i have to add or is this a bug ?

Greetz,
Rastman
Coordinator
Apr 11, 2013 at 7:26 AM
Your code looks ok so far. You won't need the projectMain.Repository.Update() calls because this will only update the project's settings (e.g. the loaded shape libraries).
I cannot reproduce the issue with this code, so perhaps you can provide a bit more information, particularly which type of entity could not be found?
The stack trace of the exception or, if you can reproduce the issue regularly, a small demo program (send it to our "support at dataweb dot de" address) would be handy.
Apr 18, 2013 at 11:17 AM
Edited Apr 18, 2013 at 11:19 AM
i dont know the type of entity but this is the exception details :

  Message=Entity not found in repository.
  Source=Dataweb.NShape
  StackTrace:
       bei Dataweb.NShape.Advanced.CachedRepository.UpdateEntity[TEntity](Dictionary`2 loadedEntities, Dictionary`2 newEntities, TEntity entity)
       bei Dataweb.NShape.Advanced.CachedRepository.DoUpdateShapes(IEnumerable`1 shapes)
       bei Dataweb.NShape.Advanced.CachedRepository.Update(IEnumerable`1 shapes)
       bei Dataweb.NShape.Commands.MoveShapeByCommand.Execute()
       bei Dataweb.NShape.Advanced.History.ExecuteAndAddCommand(ICommand command)
       bei Dataweb.NShape.Project.ExecuteCommand(ICommand command)
       bei Dataweb.NShape.SelectionTool.PerformMoveShape(IDiagramPresenter diagramPresenter)
       bei Dataweb.NShape.SelectionTool.ProcessMouseUp(IDiagramPresenter diagramPresenter, MouseState mouseState)
       bei Dataweb.NShape.SelectionTool.ProcessMouseEvent(IDiagramPresenter diagramPresenter, MouseEventArgsDg e)
       bei Dataweb.NShape.WinFormsUI.Display.OnMouseUp(MouseEventArgs e)
       bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       bei System.Windows.Forms.Control.WndProc(Message& m)
       bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       bei System.Windows.Forms.UserControl.WndProc(Message& m)
       bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       bei System.Windows.Forms.Application.Run(Form mainForm)
       bei ....Program.Main() in ....\Program.cs:Zeile 18.
  InnerException: 
I inserted and removed some shapes and connected them with a recline with an attached label by code .
After i mark all the shapes with holding the left mouse button and move them around i get this exception.
Sometimes (but very rarely) i get this exception too, when i only try to right click at a shape.
Coordinator
Apr 19, 2013 at 7:11 AM
Ok, the stack trace tells us that a shape is not found:
Dataweb.NShape.Advanced.CachedRepository.DoUpdateShapes

Can you reproduce this issue with the "NShape Designer", too?
If not:
Could you please provide me the code that created, inserts and connects the shapes, especially the code that connects the lines and the label?

Did you call Repository.InsertConnection(...) after establishing the connection between the shapes?
Apr 19, 2013 at 10:22 AM
Edited Apr 19, 2013 at 10:22 AM
No i didnt call Repository.InsertConnection(...) . Im adding connection the same way as i add my normal shapes.

This is for example how i'm inserting two steps :
//Insert Shape

Box shape1 = (Box)projectMain.Repository.GetTemplate("Template1").CreateShape();
tmpDiag.Shapes.Add(newStep);
projectMain.Repository.Insert((Shape)newStep, tmpDiag);

Box shape2 = (Box)projectMain.Repository.GetTemplate("Template1").CreateShape();
tmpDiag.Shapes.Add(newStep);
projectMain.Repository.Insert((Shape)newStep, tmpDiag);

//Connect the Shapes
 RectangularLine connection = (RectangularLine)projectMain.Repository.GetTemplate("Template2").CreateShape();
 connection.Connect(ControlPointId.FirstVertex, shape1, controlPoint1);
 connection.Connect(ControlPointId.LastVertex, shape2, controlPoint2);
 tmpDiag.Shapes.Add(connection);
 projectMain.Repository.Insert((Shape)connection, tmpDiag);

//Add Label to connection
 Dataweb.NShape.GeneralShapes.Label lable = (Dataweb.NShape.GeneralShapes.Label)projectMain.ShapeTypes["Label"].CreateInstance();
 tmpDiag.Shapes.Add(label);
projectMain.Repository.Insert((Shape)label, tmpDiag);
attachLabelToLine(connection,label);

//This function u wrote me in a previous post
 private void attachLableToLine(RectangularLine connection, Dataweb.NShape.GeneralShapes.Label label)
        {

            ControlPointId targetPtId = ControlPointId.Reference;
            Point pos1 = connection.GetControlPointPosition(ControlPointId.FirstVertex);
            Point pos2 = connection.GetControlPointPosition(ControlPointId.LastVertex);
            Point targetPos = Point.Round(new PointF(pos2.X, (pos1.Y + pos2.Y) / 2f));


            ControlPointId gluePtId = ControlPointId.None;
            foreach (ControlPointId id in label.GetControlPointIds(ControlPointCapabilities.Glue))
                gluePtId = id;

  
            label.MoveControlPointTo(gluePtId, targetPos.X, targetPos.Y, ResizeModifiers.None);
            label.Connect(gluePtId, connection, targetPtId);

            label.MoveTo(targetPos.X + 20, targetPos.Y);

        }  
Is it necessary that i insert a connection with Repository.InsertConnection(...)?
If yes, if i disconnect an existing connection and connect it to a new Shape (or Shapes) do i have to call the Repository.InsertConnection(...) again with the new Shape as it parameters?
Coordinator
Apr 19, 2013 at 11:00 AM
Yes, connections have to be inserted and removed from the repository.
label.Connect(gluePtId, connection, targetPtId);
projectMain.Repository.InsertConnection(label, gluePtId, connection, targetPtId);
Alternatives:
  • Connect the shapes first and then call Repository.InsertAll(...)
  • Create a ConnectCommand / DisconnectCommand and execute it by calling Project.ExecuteCommand(...);
Apr 22, 2013 at 9:31 AM
Edited Apr 22, 2013 at 10:46 AM
Ok i changed my code now but i still get this error. But i think i can specific my problem now.

When i delete one shape, his previous connection and previous label should be deleted too.
I do this with the following Code :
  //prev Shape
 Shape prevShape = null;
 RectangularLine prevConnection = null;
 Dataweb.NShape.GeneralShapes.Label prevLabel = null;

 //function to get the prevShape,prevConnection and prevLable  from delShape
 getPrevShapeAt(delShape, 2, out prevShape, out prevConnection, out prevLabel);
            
  //removeLabel
  prevLabel.Disconnect(10);
  projectMain.Repository.DeleteConnection( prevLabel, 10, prevConnection, 0);
  displayMain.DeleteShape( prevLabel);
  diag.Shapes.Remove( prevLabel);

  //remove Connection ("connection" is the connection at the branching point which //has the controlpoint id 3)
 var connection = prevConnection.GetConnectionInfo(ControlPointId.FirstVertex, null).OtherShape;
 projectMain.Repository.DeleteConnection(connection, 3, prevConnection, ControlPointId.FirstVertex);
 projectMain.Repository.DeleteConnection(delShape, 2, prevConnection, ControlPointId.LastVertex);

 displayMain.DeleteShape(prevConnection);
 diag.Shapes.Remove(prevConnection);

 //remove Shape
displayMain.DeleteShape(delShape);
diag.Shapes.Remove(delShape);
This all works fine. The shape,label and connection are removed from the diagram correctly.
But i noticed when i mark the shapes and move them around, the labels i removed before are still there (as you can see in the pictures below).


Image
shapes i want to remove (marked)

Image
after removing

Image
moving around marked shapes

Do i delete the labels the wrong way?
Coordinator
Apr 23, 2013 at 7:50 AM
Edited Apr 23, 2013 at 8:04 AM
I've tried to build a demo with the code you provided me but some things seems to be missing - especially the part with the branching connector shapes. The version I've written in my demo works as expected.

Nevertheless, I've some remarks:
  • You are using Display.DeleteShapes. This method not only deletes the shapes, it disconnects connected shapes and deletes connections, too, so there should be nothing left to do.
  • Can you reproduce the issue if you load the repository into the NShape designer, mark the shapes to delete (Box, RectangularLine and Label) and delete them using the context menu's "Delete" command?
  • I don't know if it's only in the sample code but you have hard coded the ControlPointId's. If you want to delete a shape, you are better off disconnecting all connected shapes in a loop:
    foreach (ShapeConnectionInfo sci in shape.GetConnectionInfos(ControlPointId.Any, null)) {
        // Check to whom the active control point id belongs to and disconnect the shapes
        if (prevConnection.HasControlPointCapability(sci.OwnPointId, ControlPointCapabilities.Glue))
            prevConnection.Disconnect(sci.OwnPointId);
        else sci.OtherShape.Disconnect(sci.OwnPointId);
    }
  • Could you please extract a small demo and send it to me (support at dataweb dot de) showing the issue above so I can find the source of the problem?
    [Update]
  • If you include the projects instead of referencing the release assemblies, you get additional checks for the repository: The Debug configuration defines REPOSITORY_CHECK, which does a lot of additional checks whether the performed actions are correct. For performance reasons, the release version doesn't.
This is what I do in my sample program:
  1. Click a button => 2 boxes, a rectangula line and a label are created and connection to each other.
  2. Select one of the boxes
  3. Click another button => The box, the connected line and the label are deleted
  4. Select the remaining box and move it => No exception is thrown.
    Is there anything that differs from what you are doing?
Apr 24, 2013 at 8:58 AM
Edited Apr 24, 2013 at 9:05 AM
Yes there is a difference :
When i only select the remaining Boxes and move them around everything works fine, too.
The problem is when i hold the left mouse button and mark all the remaining shape to move them around. Then i get the exception.

I tried it in the nshape desinger and get also an exception :

Image


The strange thing is, that everthing works fine, till i delete a label. i can delete my boxes,connection etc. without getting an error when moving them around . But as soon as i delete a label and try to move the remaining shapes around (by holding the left mouse button to mark all the shapes) this exception occurs. I've send you a xml-repository file. Perhaps u can reproduce this error.

I will also try to write a little demo programm.
Coordinator
Apr 24, 2013 at 12:19 PM
Edited Apr 24, 2013 at 12:22 PM
Thanks for your feedback. I was able to track down the issue: It is a bug in the LabelBase class.
The bug occurs whenever the label's body is not in the same cell (of the diagram's spatial index) as its glue point and is connected in this location.
Due to this fact I was not able to reproduce the issue yesterday.
:-(

The buxfix will be shipped with the next maintenance release.
Until then, you can
  • work around this issue by disconnecting the label and moving the label's glue point (important) back and forth 1 pixel before deleting the label:
label.MoveControlPointBy(10, 1, 1, ResizeModifiers.None);
label.MoveControlPointBy(10, -1, -1, ResizeModifiers.None);
  • fix the issue in the code and recompile the assemblies. The file is \Core\TextShape.cs, Class LabelBase, Method CalculateBoundingRectangle:
/// <override></override>
protected override Rectangle CalculateBoundingRectangle(bool tight) {
    Rectangle result = base.CalculateBoundingRectangle(tight);
    if (Geometry.IsValid(gluePointPos)) {
        // Calculating the pin bounds only when connected causes a problem when 
        // deleting connected labels: 
        // The number of cells calculated by CalculateCells() differs and the 
        // (connected) label is not removed completely from the diagram's spatial 
        // index.
        if (!tight /*&& IsConnected(GlueControlPoint,null) == ControlPointId.None*/) {
            tl.X = bl.X = gluePointPos.X - pinSize / 2;
            tr.X = br.X = gluePointPos.X + pinSize / 2;
            tl.Y = tr.Y = gluePointPos.Y - pinSize;
            bl.Y = br.Y = gluePointPos.Y;
            tl = Geometry.RotatePoint(gluePointPos, pinAngle, tl);
            tr = Geometry.RotatePoint(gluePointPos, pinAngle, tr);
            bl = Geometry.RotatePoint(gluePointPos, pinAngle, bl);
            br = Geometry.RotatePoint(gluePointPos, pinAngle, br);
            Rectangle pinBounds;
            Geometry.CalcBoundingRectangle(tl, tr, br, bl, out pinBounds);
            result = Geometry.UniteRectangles(result, pinBounds);
        } 
    }
    return result;
}
Apr 25, 2013 at 6:10 AM
Thank you. Everything works fine now :)
Really nice support.

Greetz Rastman