private void ViewerOnEdgeAdded(object sender, EventArgs eventArgs) { var edge = (Edge)sender; var form = new Form(); var tableLayout = new TableLayoutPanel { Dock = DockStyle.Fill }; form.Controls.Add(tableLayout); // TODO: GetEdgeTypes or something foreach (var type in graph.GetNodeTypes()) { if (type.InstanceMetatype != Repo.Metatype.Edge || type.IsAbstract) { continue; } var edgeType = type as Repo.IEdge; tableLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 25)); // TODO: We definitely need names for non-abstract edges. Maybe as attribute? var associationButton = new Button { Text = "Link", Dock = DockStyle.Fill }; associationButton.Click += (o, args) => { graph.CreateNewEdge(edgeType, edge); viewer.Graph.AddPrecalculatedEdge(edge); viewer.SetEdgeLabel(edge, edge.Label); var ep = new EdgeLabelPlacement(viewer.Graph.GeometryGraph); ep.Run(); viewer.Invalidate(); form.DialogResult = DialogResult.OK; }; associationButton.Font = new Font(associationButton.Font.FontFamily, fontSize); tableLayout.Controls.Add(associationButton, 0, tableLayout.RowCount - 1); ++tableLayout.RowCount; } var result = form.ShowDialog(); if (result == DialogResult.Cancel) { viewer.Undo(); viewer.Invalidate(); } }