I am building a simple sample application to test out MSAGL but am getting a KeyNotFoundException if I add an edge after the graph is shown.
I suppose this has to do with that I need to somehow refresh some data - or perhaps use another approach, but don't know how.
Sample:
private void MainWindow_Loaded(object sender, RoutedEventArgs e) {
GraphViewer graphViewer = new GraphViewer();
graphViewer.BindToPanel(Panel);
Graph graph = new Graph();
graph.AddEdge("A", "B");
graphViewer.MouseUp += (s, ev) =>
{
if (graphViewer.ObjectUnderMouseCursor != null)
{
graph.AddEdge("A", "C"); // BOOM!
}
};
graph.Attr.LayerDirection = LayerDirection.LR;
graphViewer.Graph = graph;
}
Exception details:
System.Collections.Generic.KeyNotFoundException was unhandled
HResult=-2146232969
Message=The given key was not present in the dictionary.
Source=mscorlib
StackTrace:
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Microsoft.Msagl.WpfGraphControl.GraphViewer.<CreateVNode>b__1d(Edge e) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\tools\WpfGraphControl\GraphViewer.cs:line 1263
at Microsoft.Msagl.WpfGraphControl.VNode.<get_OutEdges>b__10(Edge e) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\tools\WpfGraphControl\VNode.cs:line 416
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at Microsoft.Msagl.Drawing.LayoutEditor.<Edges>d__20.MoveNext() in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\Drawing\LayoutEditing\LayoutEditor.cs:line 597
at Microsoft.Msagl.Drawing.LayoutEditor.TheDefaultObjectDecoratorRemover(IViewerObject obj) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\Drawing\LayoutEditing\LayoutEditor.cs:line 454
at Microsoft.Msagl.Drawing.LayoutEditor.UnselectWithoutRemovingFromDragGroup(IViewerObject obj) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\Drawing\LayoutEditing\LayoutEditor.cs:line 573
at Microsoft.Msagl.Drawing.LayoutEditor.UnselectObjectForDragging(IViewerObject obj) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\Drawing\LayoutEditing\LayoutEditor.cs:line 567
at Microsoft.Msagl.Drawing.LayoutEditor.AnalyzeLeftMouseButtonClick() in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\Drawing\LayoutEditing\LayoutEditor.cs:line 498
at Microsoft.Msagl.Drawing.LayoutEditor.HandleMouseUpOnLayoutEnabled(MsaglMouseEventArgs args) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\Drawing\LayoutEditing\LayoutEditor.cs:line 865
at Microsoft.Msagl.Drawing.LayoutEditor.ViewerMouseUp(Object sender, MsaglMouseEventArgs args) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\Drawing\LayoutEditing\LayoutEditor.cs:line 858
at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
at Microsoft.Msagl.WpfGraphControl.GraphViewer.OnMouseUp(MouseEventArgs e) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\tools\WpfGraphControl\GraphViewer.cs:line 511
at Microsoft.Msagl.WpfGraphControl.GraphViewer.GraphCanvasRightMouseUp(Object sender, MouseButtonEventArgs e) in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\tools\WpfGraphControl\GraphViewer.cs:line 183
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
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.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
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 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at MinWpfApp.App.Main() in c:\Users\br\Desktop\MSAGL\automatic-graph-layout-master\GraphLayout\Samples\MinWpfApp\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
The solution I found that works, is to detach the graph from the graph viewer before updating the graph and then reattaching it afterwards.
That doesn't give any fancy animation effects but it appears to work.