Silverlight实用窍门系列:59.多个中心点联动多线的可拖动控件扩展为拓扑图

        在本系列的第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 下载。下面是效果图,建议下载源码之后观看。






posted @ 2012-03-13 14:09  程兴亮  阅读(3045)  评论(11编辑  收藏