一个可拖拽的多点线段(usercontrol)
、
<UserControl x:Class="GmapUserControls.DragLine" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:GmapUserControls" mc:Ignorable="d" Focusable="True" d:DesignHeight="450" d:DesignWidth="800" Loaded="UserControl_Loaded" > <Canvas x:Name="canvas2"> <Canvas.Resources> <ControlTemplate TargetType="Thumb" x:Key="markerTemplate"> <Ellipse Fill="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> </ControlTemplate> <Style TargetType="Thumb" x:Key="markerStyle"> <Setter Property="Width" Value="10"/> <Setter Property="Height" Value="10" /> <Setter Property="Visibility" Value="Hidden"/> <Setter Property="RenderTransform"> <Setter.Value> <TranslateTransform X="-5" Y="-5" /> </Setter.Value> </Setter> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Template" Value="{StaticResource markerTemplate}" /> <EventSetter Event="DragDelta" Handler="Thumb_DragDelta"/> <Style.Triggers> <DataTrigger Binding="{Binding Path=.}" Value="{x:Null}"> <Setter Property="Visibility" Value="Hidden" /> </DataTrigger> </Style.Triggers> </Style> <Style TargetType="{x:Type Line}"> <Setter Property="Cursor" Value="Cross"/> <EventSetter Event="MouseLeftButtonDown" Handler="Line_MouseLeftButtonDown" /> <EventSetter Event="MouseRightButtonDown" Handler="Line_MouseRightButtonDown"/> </Style> </Canvas.Resources> <Thumb x:Name="marker1" DataContext="{x:Null}" Canvas.Left="{Binding Path=X1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Canvas.Top="{Binding Path=Y1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Background="Red" Style="{StaticResource markerStyle}" /> <Thumb x:Name="marker2" DataContext="{x:Null}" Canvas.Left="{Binding Path=X2,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Canvas.Top="{Binding Path=Y2,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Background="Red" Style="{StaticResource markerStyle}" /> </Canvas> </UserControl>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace GmapUserControls { /// <summary> /// DragLine.xaml 的交互逻辑 /// </summary> public partial class DragLine : UserControl { private List<Point> _points; public List<Point> DragPoints { get { return _points; } set { _points = value; } } private List<Line> _lines; public List<Line> DragLines { get { return _lines; } } //Line line; public DragLine() { InitializeComponent(); _lines = new List<Line>(); } private void UserControl_Loaded(object sender, RoutedEventArgs e) { Line line; for (int i = 0; i < _points.Count - 1; i++) { Ellipse ellipse1 = new Ellipse() { Width = 5, Height = 5, Fill = Brushes.Red, RenderTransform = new TranslateTransform(-2.5, -2.5) }; Ellipse ellipse2 = new Ellipse() { Width = 5, Height = 5, Fill = Brushes.Red, RenderTransform = new TranslateTransform(-2.5, -2.5) }; line = new Line() { StrokeThickness = 1, Stroke = Brushes.Red }; line.X1 = _points[i].X; line.Y1 = _points[i].Y; line.X2 = _points[i + 1].X; line.Y2 = _points[i + 1].Y; ellipse1.SetBinding(Canvas.LeftProperty, new Binding("X1") { Source = line, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); ellipse1.SetBinding(Canvas.TopProperty, new Binding("Y1") { Source = line, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); ellipse2.SetBinding(Canvas.LeftProperty, new Binding("X2") { Source = line, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); ellipse2.SetBinding(Canvas.TopProperty, new Binding("Y2") { Source = line, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); var canvas = this.canvas2; canvas.Children.Insert(i, line); canvas.Children.Add(ellipse1); canvas.Children.Add(ellipse2); this.marker1.DataContext = line; this.marker2.DataContext = line; _lines.Add(line); for (int t = 0; t < _lines.Count - 1; t++) { _lines[t].SetBinding(Line.X2Property, new Binding("X1") { Source = _lines[t + 1], Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); _lines[t].SetBinding(Line.Y2Property, new Binding("Y1") { Source = _lines[t + 1], Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); } } } private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { var thumb = (System.Windows.Controls.Primitives.Thumb)sender; Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange); Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange); } private void Line_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { marker1.Visibility = Visibility.Visible; marker2.Visibility = Visibility.Visible; Line line = (Line)sender; int q = canvas2.Children.IndexOf(line); this.marker1.DataContext = line; this.marker2.DataContext = line; var p = e.GetPosition((Canvas)line.Parent); var p1 = new Point(line.X1, line.Y1); var p2 = new Point(line.X2, line.Y2); if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) { Line newline = new Line(); newline.Stroke = line.Stroke; newline.StrokeThickness = line.StrokeThickness; System.Windows.Controls.Primitives.Thumb thumb = null; string num = ""; if ((p1 - p).Length < 20) { newline.X2 = p1.X; newline.Y2 = p1.Y; num = "1"; } else if ((p2 - p).Length < 20) { newline.X2 = p2.X; newline.Y2 = p2.Y; num = "2"; } else { return; } newline.SetBinding(Line.X1Property, new Binding("X" + num) { Source = line, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); newline.SetBinding(Line.Y1Property, new Binding("Y" + num) { Source = line, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); var canvas = (Canvas)line.Parent; int index = canvas.Children.IndexOf(marker1); canvas.Children.Insert(index, newline); Ellipse ellipse1 = new Ellipse() { Width = 5, Height = 5, Fill = Brushes.Red, RenderTransform = new TranslateTransform() { X = -2, Y = -2 } }; Ellipse ellipse2 = new Ellipse() { Width = 5, Height = 5, Fill = Brushes.Red, RenderTransform = new TranslateTransform() { X = -2, Y = -2 } }; ellipse1.SetBinding(Canvas.LeftProperty, new Binding("X1") { Source = newline, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); ellipse1.SetBinding(Canvas.TopProperty, new Binding("Y1") { Source = newline, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); ellipse2.SetBinding(Canvas.LeftProperty, new Binding("X2") { Source = newline, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); ellipse2.SetBinding(Canvas.TopProperty, new Binding("Y2") { Source = newline, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); canvas.Children.Add(ellipse1); canvas.Children.Add(ellipse2); _lines.Add(newline); this.marker1.DataContext = newline; this.marker2.DataContext = newline; Dispatcher.BeginInvoke(new Action(() => { marker2.RaiseEvent(e); }), System.Windows.Threading.DispatcherPriority.Render); } } private void Line_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { marker1.Visibility = Visibility.Hidden; marker2.Visibility = Visibility.Hidden; } } }
后台wpf调用:
dragLine = new DragLine(); dragLine.DragPoints= new List<Point>() { new Point(400,10), new Point(90,180), new Point (100,130), new Point (170,200), new Point(300,80), new Point (150,300) }; this.grid1.Children.Add(dragLine);