Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Changing LinkStyle on run-time (Read 4563 times)
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Changing LinkStyle on run-time
Mar 16th, 2010 at 1:46pm
Print Post  
Hi Stoyan,

I have an issue here regarding changing the link type on run time. Maybe you can help me out.

I have a diagram with database tables and 3 buttons,
Re-Layout (reinitialize the diagram layout), Cascading (change the link style to Cascading) and Polyline (similar in functionality with the Cascading button).

I want the user to change if he likes the way links are painted (cascading style or polyline style).

I have the following 2 methods:

internal void SetLinkStyle(LayeredLayoutLinkType layeredLayoutLinkType)
{
(_layout as LayeredLayout).LinkType = layeredLayoutLinkType;

LinkStyle linkStyle = layeredLayoutLinkType == LayeredLayoutLinkType.Cascading ? LinkStyle.Cascading : LinkStyle.Polyline;

_ermDiagram.LinkStyle = linkStyle;

foreach (DiagramLink link in _ermDiagram.Links)
link.Style = linkStyle;

//_ermDiagram.RouteAllLinks();
}

and

public void RefreshDiagramLayout()
{
_ermDiagram.RouteAllLinks();

_layout.Arrange(_ermDiagram);//, _ermDiagram.Items);

_ermDiagram.ResizeToFitItems(25, false);
}

When the Re-layout button is clicked, the RefreshDiagramLayout() method is called. When one of the two buttons (Cascading or Polyline) are clicked, then the SetLinkStyle() method is called.

Implicit diagram LinkStyle and layered layout's LinkType are Cascading. So when the user first click on "Polyline" button, the link is indeed trasformed into a polyline (or straight) line. But when the user clicks again on "Cascading" button, the link gets a cascading shape but is no more drawn in the same way it was before the user changed the link style (both ends are drawn tangent with the source and destination tables - and this is not ok).
A "Re-layout" button click (or a call to RefreshDiagramLayout from the SetLinkStyle method) , resolve this problem but I don't want the diagram to be re-layout in order to correctly display the links.

So, please advise me what to do in order to correctly display the cascading links (without doing a diagram relayout) ?

In the SetLinkStyle() method, if I do not set the Style for every link in the diagram, the link style is not changing (shouldn't the links get the style from theirs diagram parent?)


Thanks,
Bogdan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Changing LinkStyle on run-time
Reply #1 - Mar 16th, 2010 at 1:49pm
Print Post  
The diagram properties are set as follows:

internal void SetDiagramProperties()
{
this.EnableStyledText = false;

/****************/
/* Routing */
/****************/
this.RoutingOptions.TriggerRerouting = RerouteLinks.WhileCreating;// | RerouteLinks.WhileModifying; //| RerouteLinks.WhenIntersectNode;
this.RoutingOptions.EndOrientation = MindFusion.Diagramming.Orientation.Horizontal;
this.RoutingOptions.StartOrientation = MindFusion.Diagramming.Orientation.Horizontal;
this.RoutingOptions.Anchoring = Anchoring.Reassign;

this.TableConnectionStyle = TableConnectionStyle.Rows;
this.RouteLinks = true;
this.ShadowsStyle = ShadowsStyle.ZOrder; //important for drawing the shadow in a 3D style
this.RestrictItemsToBounds = RestrictToBounds.InsideOnly;
this.AutoResize = AutoResize.AllDirections;

//this.EnableLanes = true; //-?

/*********/
/* Links */
/*********/
this.DynamicLinks = true;
this.LinkStyle = LinkStyle.Cascading;
this.LinkCrossings = LinkCrossings.Arcs;
this.LinkSegments = 3;
this.CrossingRadius = 90;
this.LinkCascadeOrientation = MindFusion.Diagramming.Orientation.Auto;
this.LinksRetainForm = false; // true
this.LinkEndsMovable = false;
this.LinksSnapToBorders = false;
this.RoundedLinks = true;
this.RoundedLinksRadius = 90;
this.LinkHandlesStyle = HandlesStyle.DashFrame;
this.SnapToAnchor = SnapToAnchor.OnCreateOrModify;

this.LinkHeadShapeSize = 3;
this.LinkHeadShape = ArrowHead.DefaultFlow;

this.LinkBaseShapeSize = 3;
this.LinkBaseShape = ArrowHead.RevWithLine;


/**************************/
/* Pens, Brushes, Colors */
/**************************/

this.BackBrush = new MFDrawing.SolidBrush(Color.White);

this.TextColor = Color.FromArgb(102, 102, 102);

this.ShadowColor = Color.FromArgb(188, 188, 188);

this.TableBrush = new MindFusion.Drawing.SolidBrush(Color.FromArgb(255, 255, 153));

this.TablePen = new MindFusion.Drawing.Pen(Color.FromArgb(235, 215, 113));

this.LinkBrush = new MindFusion.Drawing.SolidBrush(Color.FromArgb(205, 154, 52));

this.LinkPen = new MindFusion.Drawing.Pen(Color.FromArgb(205, 154, 52));

/**************************/
/* Tables and Appearance */
/**************************/

this.CellCustomDraw = CustomDraw.Full;

this.TableCustomDraw = CustomDraw.Full;

this.TableHandlesStyle = HandlesStyle.Custom;

this.CellFrameStyle = CellFrameStyle.Simple;

this.TableCaptionHeight = 7;

this.TableRowHeight = 6;

this.TableConnectionStyle = TableConnectionStyle.Rows;

this.TableStyle = TableStyle.Rectangle;
}

and the layout:

private void InitLayeredLayout()
{
LayeredLayout layeredLayout = new LayeredLayout();

layeredLayout.Anchoring = Anchoring.Reassign;
layeredLayout.NodeDistance = 20;
layeredLayout.LayerDistance = 30;
layeredLayout.SplitLayers = true;
layeredLayout.Orientation = MindFusion.Diagramming.Layout.Orientation.Horizontal;
layeredLayout.Direction = Direction.Straight;
layeredLayout.LinkType = LayeredLayoutLinkType.Cascading;
layeredLayout.IgnoreNodeSize = false; //important to avoid entitity tables overlapping
layeredLayout.StraightenLongLinks = true; //avoid the links overlapping


_layout = layeredLayout;
}
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Changing LinkStyle on run-time
Reply #2 - Mar 16th, 2010 at 2:57pm
Print Post  
Hi Bogdan,

Quote:
In the SetLinkStyle() method, if I do not set the Style for every link in the diagram, the link style is not changing (shouldn't the links get the style from theirs diagram parent?)


That's just a default value for newly drawn links, but does not affect existing ones.

Are you trying to preserve the links' ControlPoints values when changing the style? In such case you could clone ControlPoints before setting Style and restoring it after that:

PointCollection points = link.ControlPoints.Clone();
link.Style = LinkStyle.Polyline;
link.ControlPoints.Clear();
link.ControlPoints.AddRange(points);
link.UpdateFromPoints(false, true);

Or just save and restore the end points if changing the Style moves them to wrong positions.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Changing LinkStyle on run-time
Reply #3 - Mar 16th, 2010 at 4:02pm
Print Post  
Thanks for the answer,

Yes indeed, playing with the ControlPoints property seems to resolve the problem, though your code is not quite useful because the first line save the points when the Style is Cascading and then restore the same points when the style became Polyline and the link can't be drawn using these points and the new style. (LayeredLayout uses Straight LinkType).

But anyways, starting from this ideea, I could get it working, if I could catch the event fired when the link is created and/or modified. In this event I would save the ControlPoints corresponding to the style used by the link. When the style is changed by the user, these ControlPoints are restored and saved for further use, something like:

foreach (VoxidaDiagramLink link in _ermDiagram.Links)
{
link.Style = linkStyle;
link.RestoreControlPoints();
link.SaveControlPoints();
}

where:

public void SaveControlPoints()
{
if (_previousControlPoints.ContainsKey(Style))
_previousControlPoints[Style] = ControlPoints.Clone();
else
_previousControlPoints.Add(Style, ControlPoints.Clone());
}

public void RestoreControlPoints()
{
if (_previousControlPoints.ContainsKey(Style))
{
ControlPoints.Clear();
ControlPoints.AddRange(_previousControlPoints[Style]);
UpdateFromPoints(false, true);
}
}

But I don't know how to catch the moment when the link is created and also when the link is modified (when the user uses the mouse to change the tables position, the links are also updated, so the ControlPoints too). The SaveControlPoints should be called in these moments. Can you help me on this one?

I've tried overwriting the CompleteCreate or CompleteModify DiagramItem methods but they are called only when the user explicitly create or modify a link, which is not my case. (in my case the links cannot by created/modified by the user)

Thanks,
Bogdan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Changing LinkStyle on run-time
Reply #4 - Mar 16th, 2010 at 6:20pm
Print Post  
Hi Bogdan,

Can't you call this method in response to LinkCreated, LinkModified and NodeModified events? NodeModified could loop over the collection returned by GetAllLinks and run SavePoints for each link.

Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Changing LinkStyle on run-time
Reply #5 - Mar 17th, 2010 at 8:55am
Print Post  
Hi Stoyan,

LinkCreated and LinkModified do not fire when the diagram is relayout (on RefreshDiagramLayout() call). they fire only on user actions. Anyways, I save the control points in the RefreshDiagramLayout() method:

public void RefreshDiagramLayout()
{
_ermDiagram.RouteAllLinks();

_layout.Arrange(_ermDiagram);//, _ermDiagram.Items);

_ermDiagram.ResizeToFitItems(25, false);

foreach (VoxidaDiagramLink link in _ermDiagram.Links)
{
link.SaveControlPoints();
}
}

The NodeModified event is indeed fired when the Node is moved by the user and I can use it to get all links and save their control points.

But before continuing with my issue, I encounter the following problem (it is related with the LinkStyle changing and its important to solve it, in order to get going with ControlPoints save/restore ideea): If I press the "Polyline" button, the link shape changes ok to polyline, but when I start dragging a node, the link is drawn again as a Cascading style. And it remains drawn in Cascading style even when the node dragging is finished. I've checked in the NodeModifying and NodeModified events, the diagram and all link styles are set to Polyline, as expected. Yet, the link is drawn in cascading style when moving the node.

In the NodeModifying event I call the RouteAllLinks method, for correctly route the link when the nodes positions are changing:

void MyDiagram_NodeModifying(object sender, NodeValidationEventArgs e)
{
this.RouteAllLinks();
}

Can you please give me a hint on what am I doing wrong here?

Thanks,
Bogdan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Changing LinkStyle on run-time
Reply #6 - Mar 17th, 2010 at 11:03am
Print Post  
I suppose it's QuickRouter setting the link path to a cascading one. You could switch to GridRouter instead - it also uses diagonal segments in the found routes.

Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Changing LinkStyle on run-time
Reply #7 - Mar 17th, 2010 at 12:23pm
Print Post  
I've changed the link router to GridRouter but same behavior: Although in the NodeModifying event, the Style of the link is Polyline (I'm using a simple test with 2 nodes and a single link), the LinkStyle of the diagram is also Polyline, the link is layout as a cascading link.

I've also, changed the implicit diagram style to Polyline, and the default LayeredLayout link type set to LayeredLayoutLinkType.Straight (so, no need to press any button to change the style) but the same behavior is present, if the nodes are moved, the link style changes to Cascading.

Any ideas?

Thanks,
Bogdan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Changing LinkStyle on run-time
Reply #8 - Mar 17th, 2010 at 2:36pm
Print Post  
In my test the links are routed as polylines:

private void diagram_NodeModifying(object sender, NodeValidationEventArgs e)
{
     diagram.LinkRouter = new GridRouter();
     diagram.RouteAllLinks();
     diagramView.RecreateCacheImage();
}

Is "this.RouteAllLinks();" from your code a few posts back a method of your form, or are you using a class derived from Diagram?

Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Changing LinkStyle on run-time
Reply #9 - Mar 18th, 2010 at 8:38am
Print Post  
Hi Stoyan,

I'm sorry, it's my bad. Indeed, after changing the router to GridRouter, the links are routed as polylines. I was mislead by the fact that when changing the link style to polyline, the code (SetLinkStyle method) did not call the RouteAllLinks method, so the link(s) was/were firstly drawn as simply straight lines. And when I moved the node, the shape of the links changed because in the NodeModifying event, the RouteAllLinks is called. I fixed that by calling diagram.RouteAllLinks() right after changing the links style so no more straight line link shapes.

But again, this works only with GridRouter. The default QuickRouter do not route the links in polyline style.

My initial issue, was also resolved, by setting the diagram.LinkCascadeOrientation = Orientation.Horizontal.

Thanks for your help,
Bogdan
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint