/// <summary> /// Called before the <see cref="E:System.Windows.UIElement.MouseLeftButtonUp" /> event occurs. /// </summary> /// <param name="e">The data for the event.</param> /// <exception cref="System.ArgumentNullException">e</exception> protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { if (_destConnectorControl != null) { _destConnectorControl.ShowNotification = false; _destConnectorControl = null; } base.OnMouseLeftButtonUp(e); if (e == null) throw new ArgumentNullException("e"); var panel = DiagramPanel.GetParentPanel<DiagramPanel>(this); panel.Cursor = Cursors.Arrow; var connectionStart = DataContext as IDiagramItemViewModel; if (connectionStart != null) { var connectionEnd = panel.GetViewModelByLocation<IDiagramItemViewModel>(e.GetPosition(Application.Current.RootVisual)); var sourceItem = connectionStart; var destinationItem = connectionEnd; var connector = DataContext as IConnectorViewModel; if (connector != null) { connector.IsConnectionCandidate = false; sourceItem = connector.ConnectorType == ConnectorType.In ? connectionEnd : connectionStart; destinationItem = connector.ConnectorType == ConnectorType.In ? connectionStart : connectionEnd; } if (_connectorCandidate != null) { _connectorCandidate.IsConnectionCandidate = false; _connectorCandidate = null; } var panelVM = panel.DataContext as DiagramViewModel; if (_isDragging && sourceItem != null && destinationItem != null && panelVM != null && sourceItem.CanConnectTo(destinationItem, panelVM.Items).CanConnect) { var newConnection = sourceItem.CreateConnectionTo(destinationItem); if (newConnection != null) { panelVM.Items.Add(newConnection); sourceItem.ConnectTo(destinationItem); } } } CancelLink(panel); _isDragging = false; ReleaseMouseCapture(); }
/// <summary> /// Called before the <see cref="E:System.Windows.UIElement.MouseMove" /> event occurs. /// </summary> /// <param name="e">The data for the event.</param> /// <exception cref="System.ArgumentNullException">e</exception> protected override void OnMouseMove(MouseEventArgs e) { if (e == null) throw new ArgumentNullException("e"); if (!_isDragging) { if (DataContext is IConnectorViewModel) { ((IConnectorViewModel)DataContext).IsConnectionCandidate = true; } } if (_isDragging && _line != null) { var panel = DiagramPanel.GetParentPanel<DiagramPanel>(this); var position = e.GetPosition(panel); _line.X2 = position.X; _line.Y2 = position.Y; panel.Cursor = Cursors.Wait; var sourceItem = DataContext as IDiagramItemViewModel; if (sourceItem != null) { var panelVM = (DiagramViewModel)panel.DataContext; var destinationItem = panel.GetViewModelByLocation<IDiagramItemViewModel>(e.GetPosition(Application.Current.RootVisual)); if (destinationItem != null && panelVM != null && sourceItem.CanConnectTo(destinationItem, panelVM.Items).CanConnect) { panel.Cursor = Cursors.Arrow; } var item = destinationItem as IConnectorViewModel; if (item != null) { if (panelVM != null) { var connectivity = sourceItem.CanConnectTo(item, panelVM.Items); if (connectivity.CanConnect) { var destConnector = item; destConnector.IsConnectionCandidate = true; _destConnectorCandidate = destConnector; // HINT: need this because of weird behavior // when mouse pointer is over connector and IsConnectionCandidate set to true // previous line dissapears, thought it is still in panel.Children and all properties are set correctly RecreateLine(panel, destConnector.Left, destConnector.Top); } else { panel.Cursor = Cursors.Wait; var targetConnector = panel.GetDataBoundViewByLocation<IDiagramItemViewModel, ConnectorThumb>(e.GetPosition(Application.Current.RootVisual)); if (targetConnector != null) { targetConnector.NotificationMessage = connectivity.JustificationMessage; _destConnectorControl = targetConnector; } } } else { //((IConnectorViewModel)destinationItem).IsConnectionCandidate = false; panel.Cursor = Cursors.Wait; } } else { if (_destConnectorControl != null) { _destConnectorControl.ShowNotification = false; _destConnectorControl = null; } if (_destConnectorCandidate != null) { _destConnectorCandidate.IsConnectionCandidate = false; _destConnectorCandidate = null; Dispatcher.BeginInvoke(() => RecreateLine(panel, position.X, position.Y)); } } } } }