We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

ZOrder manipulation

Hi,

Lets say I have 5 different symbol which can be dragged and dropped.

When a node dragged-dropped I need to assign a ZOrder value(depending on its name) to it. Lets say sysmbol A's zorder will be 1, symbol B's 2,
symbol C's 3, etc.

so zorder of the all symbol C will be same and will always be higher then any symbol B node.

Is there any way to apply such kind of manipulation?

Regards


16 Replies

ER Eric Robishaw February 10, 2009 01:05 AM UTC

I think the easiest way to do this is by using a special implementation of layers.

Unfortunately, Syncfusion chose to duplicate the goofy implementation of layers from Visio, namely any object can be assigned to multiple layers. Dumb.

Anyhow, you can implement your own logic by creating 1 layer for each object:
LayerA, LayerB, etc...

At startup, create those layers in your diagram.

Then, watch for a node being added to the diagram. At which point, use some logic to determine which layer the node should be on.

Set that layer you desire as active/enabled, and all others inactive (the only way to make sure you assign the object to that one layer).

Then, find the zorder of the last item in that layer, and now assign your object that new zorder. Doing so will automatically update the zorder of all objects greater than this one (i.e., set new node to zindex=3, current 3 moves to 4, 4>>5, etc..) By using the layers, you know that if you inserted item B at zorder 3, for example, that the item at zorder 4 is in the next highest layer.

I've attached part of my DiagramEx class which derives from Diagram.
It includes much improved layer manipulation. It replaces the BringToFront(), BringForward(), etc... commands so that layers are not ignored.












DiagramEx_ef01b93f.zip


ER Eric Robishaw February 10, 2009 01:09 AM UTC

I forgot to include a few methods in the class.

Use this updated attachment instead.

All you have to do then for your implementation request is:
1) create layers per your logic (i.e, layerA, layerB)
2) watch for items being added
3) use my "SendNodeToLayer()" method to move it to that layer.





DiagramEx_7143a6d8.zip


AD Administrator Syncfusion Team February 10, 2009 10:08 AM UTC

Thanks Eric



AM Ajeet M Syncfusion Team February 10, 2009 11:39 AM UTC

Hi Ace,

The Layers are used for assigning some nodes with same "ZOrder" in the Diagram's model.

The implementation of the same is available in the following location:

http://help.syncfusion.com/UG/User%20Interface/Windows%20Forms/Diagram/Documents/444layers.htm

Let me know if you shall need any further clarifications in this regard.

Happy Coding!
- Ajeet




ER Eric Robishaw February 10, 2009 11:12 PM UTC

The problem with your layer implementation is that SendToBack and BringToFront() methods don't consider the layers...

If I have:

Layer 1
Object 1.1
Object 1.2

Layer 2
Object 2.1
Object 2.2

And issue a SendtoBack() of Object 2.2, it should only move behind Object 2.1, not behind 1.1.

However, that's exactly what the Diagram does in the current implementation.

The code I've provided bypasses that errant behavior.

>Hi Ace,

The Layers are used for assigning some nodes with same "ZOrder" in the Diagram's model.

The implementation of the same is available in the following location:

http://help.syncfusion.com/UG/User%20Interface/Windows%20Forms/Diagram/Documents/444layers.htm

Let me know if you shall need any further clarifications in this regard.

Happy Coding!
- Ajeet






AM Ajeet M Syncfusion Team February 11, 2009 10:33 AM UTC

Hi Eric,

The "SendToBack()" puts the "Node" at the lower most ZOrder.

Using "SendBackward()" is what fills your requirement.

Let me know if you shall need any further clarifications in this regard.

Happy Coding!
-Ajeet




ER Eric Robishaw February 12, 2009 06:50 AM UTC

I think you miss the point.

In all drawing / illustration programs that support layers (Adobe Illustrator, Photoshop, autocad, CorelDraw, GIMP, Flash, TurboCad, smartdraw, Xara, open office draw, etc..., all except Visio), sendtoback does not put an item behind items on another layer.

It just doesn't make any sense. It should only send things to the back of the current layer.

If you want to move it to the lowest zorder, you should move it first to the lowest layer, then to the lowest zorder of that layer.

If anyone else agrees, please help yourselves to the above code.





AM Ajeet M Syncfusion Team February 13, 2009 04:52 AM UTC

Hi Eric,

I am sorry that I disagree here. To make things easier for developer we had introduced both "SendToBack()" and "SendBackward()" methods.

It does makes sense, when there are 100 layers and we wish to send one of the nodes to the last layer.

We could just call the SendToBack() for the node, once, rather sending it to each intermediate layer, finally reaching the last layer!

Happy Coding!
-Ajeet




ER Eric Robishaw February 13, 2009 08:20 AM UTC

Why not have a SendToBackofLayer() method then?

But really, my beef is with your entire layer implementation.

One object should not be assignable to multiple layers. Its just nonsense and overly complicated. Only Vizio does that.

But hey, that's what opinions are for. I'm sure you guys had some good reasons for your implementation. I guess my number was busy when you called to ask my opinion (:>)








AM Ajeet M Syncfusion Team February 13, 2009 08:40 AM UTC

Hi Eric,

You are absolutely correct. Our customer's opinions have helped us achieve the current position.

It is these opinions that keep us on the track to success and improve at every stage.

I shall discuss this with my team and would see if this would be a better way to implement.

Thanks for your support and constant patronage to our products.

Warm Regards,
Ajeet




AD Administrator Syncfusion Team February 13, 2009 04:40 PM UTC

Thank you both.

I need to detect if a node is dublicated by ctrl+drag and place this new node to the appropriate layer. Which event should I use to detect this node?



ER Eric Robishaw February 13, 2009 07:08 PM UTC

Use the Diagram.Model.EventSink.NodeCollectionChanged event, and watch for evtArgs.ChangeType = Insert

at which point you can set the appropriate layer(s).

Note: this event doesn't just fire for duplication of a node, but any time a node is added including:
Group nodes (in which case you get 2 or more events, first Remove of the items followed by Insert of the group)
Ungroup: first remove of the group, then Insert of the ungrouped items
Dragging a symbol to the diagram
Pasting a symbol
And, of-course, duplicating.

I think the only way to know if nodes are being duplicated via the Control-Drag would be to superclass the MoveTool, and overload the MoveNodes() routine, use the same code from the base, but add a "IsDuplicatingFlag =true" somewhere before the call to "CloneMoveNodes()" and set to false after the call. It is during this call that the event above is raised. So, in the Model.Eventsink event described above, check for the value of this flag and act accordingly.

This might be a useful feature request for the fine folks at Syncfusion, to add such a flag. Then the user could do something like:
if ( ((MoveTool)Diagram.ActiveTool).IsDuplicating))

Come to think of it, w/o superclassing, you could just check if the active tool is of type MoveTool && the Diagram.IsMouseDown flag, && Control.ModifierKeys == Keys.Control, then I think you're safe in assuming it was a Control-Drag duplication that occurred.

If however, you want to watch for clipboard Paste duplication, then you just need to set your own flag before calling the Paste() method.









AD Administrator Syncfusion Team February 16, 2009 01:32 PM UTC


even if I click to an empty area I get: evtArgs.ChangeType = Insert
So I think I can not go anywhere by using this event.

I tried to overload MoveNodes() routine but the source is hidden so I can not add anything to the base. If I am wrong can you please send the code part?



ER Eric Robishaw February 16, 2009 08:06 PM UTC

First, are you sure you're using Diagram.Model.EventSink and not Diagram.EventSink for the nodecollectionchanged event?

You should not get an insert clicking a blank area...

If you need the code for MoveTool.MoveNodes() routine use Reflector (you probably need the full Syncfusion code license to legally use though)

Eric





AD Administrator Syncfusion Team February 18, 2009 03:32 PM UTC

Hi Eric,
You are right about the event, now I have what I wanted. But still I need to fix the order of the layers.

what I mean by saying "fixing the order of layer" is;

I create 10 layers. When I add symbol A to the scene and symbol A is placed to the appropriate layer, lets call it layerA. After that if I add symbol B, program places it to the layerB(as expected) and symbol B will be over of the symbol A. If I add another symbol A it will be placed to the LayerA and this two symbol A will be under the symbol B.

Everything seems to work correctly but what I want is; symbol B should be under the symbol A whenever it is added to the scene. If symbol B is first added to the scene before any symbol A it works correctly but if I delete all symbol B and add it to the scene again it will appear over symbol A.

Is there an easy way to do this?




AD Administrator Syncfusion Team February 18, 2009 04:48 PM UTC

forget it, I found a simpler way.
Thanks for your help


Loader.
Live Chat Icon For mobile
Up arrow icon