在本系列的第17篇文章中“Silverlight实用窍门系列:17.中心点联动多线的可拖动控件(绘制工程图、拓扑图基础) ”,制作了基本的中心联动图标。有园友对此图的扩展不是很清晰,所以在本文中我们将在那基础上做一个简易的拓扑图。

        首先:将黄球为中心,绿球为圆圈的节点封装为一个子控件,然后提供一个接口,该接口可以接收一条外部的直线,并且这个接口可以指定在子控件中外部链接线的起始点还是结束点。      

 

  1. public partial class UCCircle : UserControl 
  2.     public UCCircle(double lineCount, double lineLenth, double centerX, double centerY) 
  3.     { 
  4.         InitializeComponent(); 
  5.         //让img1图片控件具有MouseDragElementBehavior行为,且为让此控件在拖动过程中执行dragBehavior_Dragging事件。 
  6.         dragBehavior.Attach(this.img1); 
  7.         dragBehavior.Dragging += new MouseEventHandler(dragBehavior_Dragging); 
  8.         //设置img1可见,设置其初始位置。 
  9.         img1.SetValue(Canvas.LeftProperty, centerX - 22.0); 
  10.         img1.SetValue(Canvas.TopProperty, centerY - 22.0); 
  11.         AddChirldren(lineCount, lineLenth, centerX, centerY); 
  12.     } 
  13.     MouseDragElementBehavior dragBehavior = new MouseDragElementBehavior(); 
  14.     //放所有的线的集合 
  15.     private List<ucLine> ucLineList = new List<ucLine>(); 
  16.     private void AddChirldren(double lineCount, double lineLenth, double centerX, double centerY) 
  17.     { 
  18.         //设置平均角度 
  19.         double angle = 360.0 / lineCount; 
  20.         //设置线的起始点的坐标 
  21.         for (int i = 0; i < lineCount; i++) 
  22.         { 
  23.             ucLine dline = new ucLine(); 
  24.             //设置线的半径 
  25.             dline.R = lineLenth; 
  26.             //设置线的起始点的坐标 
  27.             dline.CenterX = centerX; 
  28.             dline.CenterY = centerY; 
  29.             XX = centerX; 
  30.             YY = centerY; 
  31.             //设置这根线的角度 
  32.             dline.AngleAll = angle * (i); 
  33.             CanvasDevice.Children.Add(dline); 
  34.             //将所有的线添加到线集合中去,以供拖动过程中使用 
  35.             ucLineList.Add(dline); 
  36.         } 
  37.     } 
  38.     /// <summary> 
  39.     /// 设置连接两个圈中心的线条 
  40.     /// </summary> 
  41.     public void SetLinkLine(LinkLineModel lineModel) 
  42.     { 
  43.  
  44.         if (lineModel.PointType == PoiType.StartPoint) 
  45.         { 
  46.             lineModel.LinkLine.X1 = XX; 
  47.             lineModel.LinkLine.Y1 = YY; 
  48.         } 
  49.         else 
  50.         { 
  51.             lineModel.LinkLine.X2 = XX; 
  52.             lineModel.LinkLine.Y2 = YY; 
  53.         } 
  54.         if (LinkLineList == null
  55.             LinkLineList = new List<LinkLineModel>(); 
  56.         LinkLineList.Add(lineModel); 
  57.  
  58.     } 
  59.     /// <summary> 
  60.     /// 中心点连接线的列表 
  61.     /// </summary> 
  62.     public List<LinkLineModel> LinkLineList { set; get; } 
  63.  
  64.     //移动后的中心点位置 
  65.     public double XX { get; set; } 
  66.     public double YY { get; set; } 
  67.  
  68.     /// <summary> 
  69.     /// img1被拖动的时候触发的事件 
  70.     /// </summary> 
  71.     /// <param name="sender"></param> 
  72.     /// <param name="e"></param> 
  73.     void dragBehavior_Dragging(object sender, MouseEventArgs e) 
  74.     { 
  75.         MouseDragElementBehavior dragBehavior2 = sender as MouseDragElementBehavior; 
  76.         //获取到控件被拖动后的位置坐标 
  77.         double x1 = dragBehavior2.X + 22; 
  78.         double y1 = dragBehavior2.Y + 22; 
  79.         XX = x1; 
  80.         YY = y1; 
  81.         foreach (ucLine dline in ucLineList) 
  82.         { 
  83.             //设置lineD线的起点坐标为移动后的坐标位置 
  84.             dline.LineD.X1 = x1; 
  85.             dline.LineD.Y1 = y1; 
  86.         } 
  87.  
  88.         //设置起始点或者终结点的位置 
  89.         foreach (LinkLineModel linemodel in LinkLineList) 
  90.         { 
  91.             if (linemodel.PointType == PoiType.StartPoint) 
  92.             { 
  93.                 linemodel.LinkLine.X1 = XX; 
  94.                 linemodel.LinkLine.Y1 = YY; 
  95.             } 
  96.             else 
  97.             { 
  98.                 linemodel.LinkLine.X2 = XX; 
  99.                 linemodel.LinkLine.Y2 = YY; 
  100.             } 
  101.         } 
  102.  
  103.     } 

        UCCircle.Xaml代码如下:

 

  1. <Grid x:Name="LayoutRoot" Background="White"
  2.     <Canvas x:Name="CanvasDevice" > 
  3.  
  4.         <Image x:Name="img1" Source="yellow.png" Width="44" Canvas.ZIndex="300" Height="44"></Image> 
  5.     </Canvas> 
  6. </Grid> 

        接口中指定线条是起始点还是终结点,以供子控件识别并且随时改变两个子控件中的连接线位置。

 

  1. public class LinkLineModel 
  2.     /// <summary> 
  3.     /// 起点线还是终点线 
  4.     /// </summary> 
  5.     public PoiType PointType { get; set; } 
  6.  
  7.     /// <summary> 
  8.     /// 线 
  9.     /// </summary> 
  10.     public Line LinkLine { get; set; } 
  11.  
  12.     /// <summary> 
  13.     /// 线条名字 
  14.     /// </summary> 
  15.     public string LineName { get; set; } 

        定义了一个枚举如下:

 

  1. /// <summary> 
  2. /// 指定点的类型是起始点还是终结点 
  3. /// </summary> 
  4. public enum PoiType 
  5. {  
  6.     StartPoint, 
  7.     EndPoint 

        最后看MainPage.xaml.cs代码如下,构造了三个子控件,两条子控件之间的连接线:

 

  1. public partial class MainPage : UserControl 
  2.     public MainPage() 
  3.     { 
  4.         InitializeComponent(); 
  5.         CanvasDevice.Children.Clear(); 
  6.  
  7.         //连接uc和uc1的线条 
  8.         Line line = new Line(); 
  9.         line.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)); 
  10.         line.AllowDrop = true
  11.  
  12.         //连接uc1和uc2的线条 
  13.         Line line2 = new Line(); 
  14.         line2.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)); 
  15.         line2.AllowDrop = true
  16.  
  17.         //声明三个圆心的图 
  18.         UCCircle uc = new UCCircle(5, 100, 250, 150); 
  19.         UCCircle uc1 = new UCCircle(6, 100, 160, 370); 
  20.         UCCircle uc2 = new UCCircle(6, 100, 450, 400); 
  21.  
  22.         //设置线条一 在子控件中 
  23.         uc.SetLinkLine(new LinkLineModel() { LinkLine= line, PointType= PoiType.StartPoint }); 
  24.         uc1.SetLinkLine(new LinkLineModel() { LinkLine = line, PointType = PoiType.EndPoint }); 
  25.  
  26.         //设置线条二 在子控件中 
  27.         uc1.SetLinkLine(new LinkLineModel() { LinkLine = line2, PointType = PoiType.StartPoint }); 
  28.         uc2.SetLinkLine(new LinkLineModel() { LinkLine = line2, PointType = PoiType.EndPoint }); 
  29.  
  30.         //将线条和子空间添加到Canvas中 
  31.         CanvasDevice.Children.Add(line); 
  32.         CanvasDevice.Children.Add(line2); 
  33.         CanvasDevice.Children.Add(uc); 
  34.         CanvasDevice.Children.Add(uc1); 
  35.         CanvasDevice.Children.Add(uc2); 
  36.     } 

        如需源码请点击 SLLinkLine.rar 下载。下面是效果图,建议下载源码之后观看。