在本系列的第17篇文章中“Silverlight实用窍门系列:17.中心点联动多线的可拖动控件(绘制工程图、拓扑图基础) ”,制作了基本的中心联动图标。有园友对此图的扩展不是很清晰,所以在本文中我们将在那基础上做一个简易的拓扑图。
首先:将黄球为中心,绿球为圆圈的节点封装为一个子控件,然后提供一个接口,该接口可以接收一条外部的直线,并且这个接口可以指定在子控件中外部链接线的起始点还是结束点。
- public partial class UCCircle : UserControl
- {
- public UCCircle(double lineCount, double lineLenth, double centerX, double centerY)
- {
- InitializeComponent();
- //让img1图片控件具有MouseDragElementBehavior行为,且为让此控件在拖动过程中执行dragBehavior_Dragging事件。
- dragBehavior.Attach(this.img1);
- dragBehavior.Dragging += new MouseEventHandler(dragBehavior_Dragging);
- //设置img1可见,设置其初始位置。
- img1.SetValue(Canvas.LeftProperty, centerX - 22.0);
- img1.SetValue(Canvas.TopProperty, centerY - 22.0);
- AddChirldren(lineCount, lineLenth, centerX, centerY);
- }
- MouseDragElementBehavior dragBehavior = new MouseDragElementBehavior();
- //放所有的线的集合
- private List<ucLine> ucLineList = new List<ucLine>();
- private void AddChirldren(double lineCount, double lineLenth, double centerX, double centerY)
- {
- //设置平均角度
- double angle = 360.0 / lineCount;
- //设置线的起始点的坐标
- for (int i = 0; i < lineCount; i++)
- {
- ucLine dline = new ucLine();
- //设置线的半径
- dline.R = lineLenth;
- //设置线的起始点的坐标
- dline.CenterX = centerX;
- dline.CenterY = centerY;
- XX = centerX;
- YY = centerY;
- //设置这根线的角度
- dline.AngleAll = angle * (i);
- CanvasDevice.Children.Add(dline);
- //将所有的线添加到线集合中去,以供拖动过程中使用
- ucLineList.Add(dline);
- }
- }
- /// <summary>
- /// 设置连接两个圈中心的线条
- /// </summary>
- public void SetLinkLine(LinkLineModel lineModel)
- {
- if (lineModel.PointType == PoiType.StartPoint)
- {
- lineModel.LinkLine.X1 = XX;
- lineModel.LinkLine.Y1 = YY;
- }
- else
- {
- lineModel.LinkLine.X2 = XX;
- lineModel.LinkLine.Y2 = YY;
- }
- if (LinkLineList == null)
- LinkLineList = new List<LinkLineModel>();
- LinkLineList.Add(lineModel);
- }
- /// <summary>
- /// 中心点连接线的列表
- /// </summary>
- public List<LinkLineModel> LinkLineList { set; get; }
- //移动后的中心点位置
- public double XX { get; set; }
- public double YY { get; set; }
- /// <summary>
- /// img1被拖动的时候触发的事件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- void dragBehavior_Dragging(object sender, MouseEventArgs e)
- {
- MouseDragElementBehavior dragBehavior2 = sender as MouseDragElementBehavior;
- //获取到控件被拖动后的位置坐标
- double x1 = dragBehavior2.X + 22;
- double y1 = dragBehavior2.Y + 22;
- XX = x1;
- YY = y1;
- foreach (ucLine dline in ucLineList)
- {
- //设置lineD线的起点坐标为移动后的坐标位置
- dline.LineD.X1 = x1;
- dline.LineD.Y1 = y1;
- }
- //设置起始点或者终结点的位置
- foreach (LinkLineModel linemodel in LinkLineList)
- {
- if (linemodel.PointType == PoiType.StartPoint)
- {
- linemodel.LinkLine.X1 = XX;
- linemodel.LinkLine.Y1 = YY;
- }
- else
- {
- linemodel.LinkLine.X2 = XX;
- linemodel.LinkLine.Y2 = YY;
- }
- }
- }
- }
UCCircle.Xaml代码如下:
- <Grid x:Name="LayoutRoot" Background="White">
- <Canvas x:Name="CanvasDevice" >
- <Image x:Name="img1" Source="yellow.png" Width="44" Canvas.ZIndex="300" Height="44"></Image>
- </Canvas>
- </Grid>
接口中指定线条是起始点还是终结点,以供子控件识别并且随时改变两个子控件中的连接线位置。
- public class LinkLineModel
- {
- /// <summary>
- /// 起点线还是终点线
- /// </summary>
- public PoiType PointType { get; set; }
- /// <summary>
- /// 线
- /// </summary>
- public Line LinkLine { get; set; }
- /// <summary>
- /// 线条名字
- /// </summary>
- public string LineName { get; set; }
- }
定义了一个枚举如下:
- /// <summary>
- /// 指定点的类型是起始点还是终结点
- /// </summary>
- public enum PoiType
- {
- StartPoint,
- EndPoint
- }
最后看MainPage.xaml.cs代码如下,构造了三个子控件,两条子控件之间的连接线:
- public partial class MainPage : UserControl
- {
- public MainPage()
- {
- InitializeComponent();
- CanvasDevice.Children.Clear();
- //连接uc和uc1的线条
- Line line = new Line();
- line.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
- line.AllowDrop = true;
- //连接uc1和uc2的线条
- Line line2 = new Line();
- line2.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
- line2.AllowDrop = true;
- //声明三个圆心的图
- UCCircle uc = new UCCircle(5, 100, 250, 150);
- UCCircle uc1 = new UCCircle(6, 100, 160, 370);
- UCCircle uc2 = new UCCircle(6, 100, 450, 400);
- //设置线条一 在子控件中
- uc.SetLinkLine(new LinkLineModel() { LinkLine= line, PointType= PoiType.StartPoint });
- uc1.SetLinkLine(new LinkLineModel() { LinkLine = line, PointType = PoiType.EndPoint });
- //设置线条二 在子控件中
- uc1.SetLinkLine(new LinkLineModel() { LinkLine = line2, PointType = PoiType.StartPoint });
- uc2.SetLinkLine(new LinkLineModel() { LinkLine = line2, PointType = PoiType.EndPoint });
- //将线条和子空间添加到Canvas中
- CanvasDevice.Children.Add(line);
- CanvasDevice.Children.Add(line2);
- CanvasDevice.Children.Add(uc);
- CanvasDevice.Children.Add(uc1);
- CanvasDevice.Children.Add(uc2);
- }
- }
如需源码请点击 SLLinkLine.rar 下载。下面是效果图,建议下载源码之后观看。