I have a custom connection class as shown below. I have removed the 5 connectors of my nodes ("Auto", "Left", "Right", "Top", "Bottom") and added my own connectors "In" and "Out".
public class MyChartConnection : RadDiagramConnection
{
public MyChartConnection(MyLink link)
: base()
{
SourceConnectorPosition = /*ConnectorPosition.Auto*/ "in";
SourceCapType = link.SourceCapType;
TargetConnectorPosition = /*ConnectorPosition.Auto*/ "out";
TargetCapType = link.TargetCapType;
}
}
This crashes when I try to apply your TreeLayout(). Apparently, it cannot find the "Bottom" connector... Should I use another layout class? Do I have to implement my own layout class?
12 Answers, 1 is accepted
this is the same bug as the one which was recorded in PITS and has been resolved on January 9th.
I have a working example with the current codebase but I reckon you'll have to wait till Q1.2013 is out.
Sorry for this.
Francois
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
Same problem!
---------------------------
---------------------------
System.Exception: Connector 'Bottom' does not exist.
at Telerik.Windows.Controls.RadDiagramConnection.ResolveSourceConnector() in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 955
at Telerik.Windows.Controls.RadDiagramConnection.OnSourceConnectorPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 902
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at Telerik.Windows.Controls.RadDiagramConnection.set_SourceConnectorPosition(String value) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 352
at Telerik.Windows.Diagrams.Core.OrgTreeRouter.DirectionalRouter.SetSourceAndTargetConnectors() in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\OrgTreeRouter.cs:line 93
at Telerik.Windows.Diagrams.Core.OrgTreeRouter.TreeRouterBase.GetRoute(IConnection connection, Double connectionSpacing) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\OrgTreeRouter.cs:line 332
at Telerik.Windows.Diagrams.Core.OrgTreeRouter.GetRoutePoints(IConnection connection, Boolean showLastLine) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\OrgTreeRouter.cs:line 66
at Telerik.Windows.Diagrams.Core.RoutingService.BuildRoute(IConnection connection) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Services\RoutingService.cs:line 46
at Telerik.Windows.Controls.Diagrams.GeometryFactory.CreateConnectionGeometry(IConnection connection, RoutingService routingService) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Utilities\GeometryFactory.cs:line 346
at Telerik.Windows.Controls.RadDiagramConnection.UpdateGeometryOverride() in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 852
at Telerik.Windows.Controls.RadDiagramConnection.Update(Boolean isManipulating) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 805
at Telerik.Windows.Controls.RadDiagramConnection.Telerik.Windows.Diagrams.Core.IConnection.Update(Boolean isManipulating) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 525
at Telerik.Windows.Diagrams.Core.GraphController.UpdateConnectionsAndCheckForSelection(IShape shape) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Controllers\GraphController.cs:line 707
at Telerik.Windows.Diagrams.Core.GraphController.OnShapePropertyChanged(Object sender, PropertyEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Controllers\GraphController.Services.cs:line 422
at Telerik.Windows.Controls.Diagrams.RadDiagramItem.OnPropertyChanged(String propertyName) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramItem.cs:line 902
at Telerik.Windows.Controls.Diagrams.RadDiagramItem.OnSizeChanged(Size newSize, Size oldSize) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramItem.cs:line 992
at Telerik.Windows.Controls.Diagrams.RadDiagramItem.DiagramItemSizeChanged(Object sender, SizeChangedEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramItem.cs:line 1188
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.FrameworkElement.OnRenderSizeChanged(SizeChangedInfo sizeInfo)
at System.Windows.ContextLayoutManager.fireSizeChangedEvents()
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
---------------------------
OK
---------------------------
And when trying to create a manual connection I now get the error below. The only way to get rid of the errors is to leave the original connectors...
---------------------------
---------------------------
System.ArgumentException: No neighour corners found!
at Telerik.Windows.Diagrams.Core.InflatedRectRouter.GetNeighborCorners(String orientation, Rect rect, Point& n1, Point& n2) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\InflatedRectRouter.cs:line 521
at Telerik.Windows.Diagrams.Core.InflatedRectRouter.GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, Rect rectSink, Boolean& flag) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\InflatedRectRouter.cs:line 355
at Telerik.Windows.Diagrams.Core.InflatedRectRouter.GetRoutePoints(ConnectorInfo source, ConnectorInfo target, Boolean showLastLine) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\InflatedRectRouter.cs:line 64
at Telerik.Windows.Diagrams.Core.InflatedRectRouter.GetRoutePoints(IConnection connection, Boolean showLastLine) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Routing\InflatedRectRouter.cs:line 271
at Telerik.Windows.Diagrams.Core.RoutingService.BuildRoute(IConnection connection) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Services\RoutingService.cs:line 50
at Telerik.Windows.Controls.Diagrams.GeometryFactory.CreateConnectionGeometry(IConnection connection, RoutingService routingService) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Utilities\GeometryFactory.cs:line 346
at Telerik.Windows.Controls.RadDiagramConnection.UpdateGeometryOverride() in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 852
at Telerik.Windows.Controls.RadDiagramConnection.Update(Boolean isManipulating) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 805
at Telerik.Windows.Controls.RadDiagramConnection.Telerik.Windows.Diagrams.Core.IConnection.Update(Boolean isManipulating) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 525
at Telerik.Windows.Diagrams.Core.GraphController.OnConnectionPropertyChanged(Object sender, PropertyEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Controllers\GraphController.Services.cs:line 349
at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
at Telerik.Windows.Controls.Diagrams.RadDiagramItem.OnPropertyChanged(String propertyName) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramItem.cs:line 902
at Telerik.Windows.Controls.RadDiagramConnection.set_EndPoint(Point value) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\Visuals\RadDiagramConnection.cs:line 340
at Telerik.Windows.Diagrams.Core.ConnectionTool.MouseMove(PointerArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Tools\ConnectionTool.cs:line 89
at Telerik.Windows.Diagrams.Core.ToolService.<>c__DisplayClassc.<MouseMove>b__b(IMouseListener tool) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Tools\ToolService.cs:line 142
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
at Telerik.Windows.Diagrams.Core.ToolService.MouseMove(PointerArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Tools\ToolService.cs:line 142
at Telerik.Windows.Diagrams.Core.GraphController.MouseMove(PointerArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Core\Controllers\GraphController.cs:line 198
at Telerik.Windows.Controls.RadDiagram.OnMouseMove(MouseEventArgs e) in c:\TB\117\WPF_Scrum\Current_HotFix\Sources\Diagrams\Diagrams\RadDiagram.cs:line 381
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
---------------------------
OK
---------------------------
Please fix this as soon as possible! This is pretty much a blocker for us.
This bug is fixed but it won't be included in our internal builds. It will be included in the upcoming Official Q1 Release is mid-February. This mainly because it must go through our testing procedures successfully. On the other hand, we have missed to schedule it for Q1 in PITS, please excuse us for the inconvenience caused.
Kind regards,Petar Mladenov
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
1) Add node A.
2) Add node B.
3) Not needed, but here for clarity: Rearrange the nodes so that B is above A.
4) Connect from B's bottom connector to A's top connector.
5) The nodes exchange positions, resulting in the attached image. (A is above B.)
Do you rely on ZIndex or some other weird variable when arranging the nodes? I believe this bug is the root of all problems we see when laying out our nodes.
Could you please confirm that these provided steps are independent from scenarios where some shapes have multiple parents ? Several months ago you needed some kind of topological sorting and we explained that this currently cannot be achieved out of the box with TreeLayout and you will need custom Layout method or at least a method that works after the work of the TreeLayout (to arrange the additional parent nodes).
If this is not the case could you please check out our test project where we are unable to reproduce similar issue. We delete a connection, then create manually new connections with mouse connecting custom connectors and the Layout does not replace the source and target shapes. Please let us know if we are missing anything in the attached sample.
We do not rely on ZIndex when arranging the nodes. We use Position, Width, Height. And we also determine which node of the given two is the father, in tree with root - this is the one closer to the root.
Petar Mladenov
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
I'll try your sample project right away.
1) Copy a node (Ctrl+C).
2) Remove all nodes (Ctrl+A, Del).
3) Paste node #1 (Ctrl+V).
4) Paste node #2 (Ctrl+V).
5) Move node #2 above node #1.
6) Connect them.
7) Press "Layout".
Voilà !
The Layout Button invokes the function PrepareAndLayout:
private
void
PrepareAndLayout()
{
TreeLayoutSettings settings =
new
TreeLayoutSettings()
{
TreeLayoutType = TreeLayoutType.TreeDown,
VerticalDistance = 100,
UnderneathHorizontalOffset = 50,
UnderneathVerticalTopOffset = 50,
UnderneathVerticalSeparation = 60
};
settings.Roots.Add(
this
.diagram.Shapes[0]);
OrgTreeRouter router =
new
OrgTreeRouter()
{
TreeLayoutType = TreeLayoutType.TreeDown,
ConnectionOuterSpacing = 20,
};
this
.diagram.RoutingService.Router = router;
this
.diagram.Layout(LayoutType.Tree, settings);
}
Petar Mladenov
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
No, when there is no root set, the algorithm finds a root on the basis of longest paths in the graph:
/// <summary>
/// Attempts to find a tree root by looking at the longest paths in the graph.
/// </summary>
/// <remarks>The algorithms looks for all shortest paths between all vertices, which means it will also function for disconnected graphs but will return the root
/// of the tree with longest path.</remarks>
/// <returns>A tree root or <c>null</c> is none was found.
/// </returns>
public
TNode FindTreeRoot()
{
Petar Mladenov
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Adding all nodes that have no connections from above (i.e. input connectors are either not present or have no connections) solved the issue.