| <Grid |
| Background="#000123" MouseLeftButtonDown="UIElement_OnMouseLeftButtonDown" MouseMove="UIElement_OnMouseMove" PreviewMouseLeftButtonUp="UIElement_OnPreviewMouseLeftButtonUp"> |
| |
| <UniformGrid |
| Margin="25" |
| Columns="3" Rows="3"> |
| <UniformGrid.Resources> |
| <ControlTemplate x:Key="PointControlTemplate"> |
| <Grid> |
| <Ellipse |
| Width="35" Height="35" |
| Fill="#3B87E7" Opacity=".3"> |
| <Ellipse.Effect> |
| <DropShadowEffect |
| BlurRadius="5" ShadowDepth="3" |
| Color="#3B87E7" /> |
| </Ellipse.Effect> |
| |
| </Ellipse> |
| |
| <Ellipse |
| Width="15" Height="15" |
| Fill="#FFFEFF" Opacity=".8" /> |
| |
| </Grid> |
| </ControlTemplate> |
| <Style TargetType="ContentControl"> |
| <Setter Property="Template" Value="{StaticResource PointControlTemplate}" /> |
| </Style> |
| </UniformGrid.Resources> |
| |
| <ContentControl /> |
| <ContentControl /> |
| <ContentControl /> |
| <ContentControl /> |
| <ContentControl /> |
| <ContentControl /> |
| <ContentControl /> |
| <ContentControl /> |
| <ContentControl /> |
| |
| </UniformGrid> |
| |
| </Grid> |
| private readonly HashSet<ContentControl> points = new(); |
| private Line? currentLine = null; |
| |
| |
| private static Line CreateLine(Point startPoint, Color color) |
| { |
| var line = new Line(); |
| |
| line.X1 = line.X2 = startPoint.X; |
| line.Y1 = line.Y2 = startPoint.Y; |
| line.Fill = line.Stroke = new SolidColorBrush(color); |
| line.StrokeThickness = 10; |
| line.StrokeStartLineCap = line.StrokeEndLineCap = PenLineCap.Round; |
| line.IsHitTestVisible = false; |
| |
| return line; |
| } |
| |
| |
| private static Point GetPointCenter(ContentControl point, Grid grid) |
| { |
| var center = point.TranslatePoint(new Point(point.ActualWidth / 2, point.ActualHeight / 2), grid); |
| |
| return center; |
| } |
| |
| |
| private void CreateCurrentLine(ContentControl point, Grid grid) |
| { |
| |
| var startPoint = GetPointCenter(point, grid); |
| |
| var line = CreateLine(startPoint, Colors.DodgerBlue); |
| |
| grid.Children.Add(line); |
| |
| this.currentLine = line; |
| } |
| |
| |
| private void FinishedCurrentLine(ContentControl point, Grid grid) |
| { |
| if (this.currentLine == null) |
| { |
| return; |
| } |
| |
| var endPoint = GetPointCenter(point, grid); |
| this.currentLine.X2 = endPoint.X; |
| this.currentLine.Y2 = endPoint.Y; |
| |
| this.points.Add(point); |
| } |
| |
| private void UIElement_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) |
| { |
| if (e.Source is ContentControl point && sender is Grid grid) |
| { |
| |
| this.CreateCurrentLine(point, grid); |
| } |
| } |
| |
| private void UIElement_OnMouseMove(object sender, MouseEventArgs e) |
| { |
| if (this.currentLine == null || sender is not Grid grid) |
| { |
| |
| return; |
| } |
| |
| if (e.Source is ContentControl point && !this.points.Contains(point)) |
| { |
| |
| this.FinishedCurrentLine(point, grid); |
| |
| |
| this.CreateCurrentLine(point, grid); |
| } |
| else |
| { |
| var position = e.GetPosition(grid); |
| this.currentLine.X2 = position.X; |
| this.currentLine.Y2 = position.Y; |
| } |
| } |
| |
| private void UIElement_OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) |
| { |
| |
| if (sender is not Grid grid) |
| { |
| return; |
| } |
| |
| var lines = grid.Children.OfType<Line>().ToArray(); |
| Array.ForEach(lines, it => grid.Children.Remove(it)); |
| |
| this.points.Clear(); |
| |
| this.currentLine = null; |
| } |