在本系列的第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 下載。下面是效果圖,建議下載源碼之后觀看。