Silverlight实用窍门系列:17.中心点联动多线的可拖动控件(绘制工程图、拓扑图基础)【附带源码实例】

简介:

  本节是继上节所讲述的基础上做出一些调整而来,如有疑问可参考上节文章。

        在实际项目中可能会遇到绘制各类工程图或者网络拓扑图之类的情况,这类图基本上都是以设备加线的方式连接在一起的。那么一个中心设备连接多个外围设备的展示方式就是本节需要讲述的内容。上节已经讲了如何绘制一个以某点为圆心绘制出多条线,且线和线之间的角度需要相同来组成一个圆的图。在这个图的中心点加一个设备牵动所有的线的中心点的变化同时在外围点也加一个设备。中心设备和外围设备都可以随意拖动。中心设备的拖动牵连所有与中心设备关联的设备拖动。下面请看Silverlight运行预览图:

        在Photoshop里面绘画两个不同颜色的球(绿色和黄色),其直径皆为44像素,保存为Png图片。再在Silverlight项目中添加这两个球的图片。设置黄球图片为中心点,在MainPage.xaml文件中的Canvas下面添加此球图片:
< Image x:Name = " img1 "  Source = " yellow.png "  Width = " 44 "  Visibility = " Collapsed "  Canvas.ZIndex = " 300 "  Height = " 44 " ></ Image >
        设置这个图片可以被拖动,且在拖动的同时让所有的线的起始点始终在这个圆的圆心位置,需要使用行为MouseDragElementBehavior,所以引入Microsoft.Expression.Interactions.dll、Microsoft.Expression.Prototyping.Interactivity.dll和System.Windows.Interactivity.dll。并且在代码也中using Microsoft.Expression.Interactivity.Layout;。此时MainPage.xaml.cs的代码如下:
复制代码
public   partial   class  MainPage : UserControl
{
public  MainPage()
{
InitializeComponent();
// 让img1图片控件具有MouseDragElementBehavior行为,且为让此控件在拖动过程中执行dragBehavior_Dragging事件。
dragBehavior.Attach( this .img1);
dragBehavior.Dragging 
+=   new  MouseEventHandler(dragBehavior_Dragging);
// 初始化时默认点击函数
button1_Click( new   object (),  new  RoutedEventArgs());
}
MouseDragElementBehavior dragBehavior 
=   new  MouseDragElementBehavior();
// 放所有的线的集合
private  List < ucLine >  ucLineList = new  List < ucLine > ();
private   void  button1_Click( object  sender, RoutedEventArgs e)
{
CanvasDevice.Children.Clear();
// 获取需要设置多少条线
double  lineCount = double .Parse(( this .comboBox1.SelectedItem  as  ComboBoxItem).Content.ToString());
// 获取需要设置的线的长度
double  lineLenth  =   double .Parse( this .textBox1.Text.ToString());
// 设置平均角度
double  angle  =   360.0   /  lineCount;
// 设置线的起始点的坐标
double  centerX  =   250 ;
double  centerY  =   250 ;
for  ( int  i  =   0 ; i  <  lineCount; i ++ )
{
ucLine dline 
=   new  ucLine();
// 设置线的半径
dline.R  =  lineLenth;
// 设置线的起始点的坐标
dline.CenterX  =  centerX;
dline.CenterY 
=  centerY;
// 设置这根线的角度
dline.AngleAll  =  angle  *  (i);
CanvasDevice.Children.Add(dline);
// 将所有的线添加到线集合中去,以供拖动过程中使用
ucLineList.Add(dline);
}
// 设置img1可见,设置其初始位置。
this .img1.Visibility  =  Visibility.Visible;
img1.SetValue(Canvas.LeftProperty, centerX 
-   22.0 );
img1.SetValue(Canvas.TopProperty, centerY 
-   22.0 );
}
///   <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 ;
foreach  (ucLine dline  in  ucLineList)
{
// 设置lineD线的起点坐标为移动后的坐标位置
dline.LineD.X1  =  x1;
dline.LineD.Y1 
=  y1;
}

}
}
复制代码

        这些代码是在上一节的基础上进行了一部分的修改,所有的注释都在代码中,需要注意的是比如double x1 = dragBehavior2.X + 22,这里的22这个数字是黄球的半径,是为了让这些线集中在黄球的中心点位置上,而不是集中在黄球的左上角位置。这个是计算的坐标。

        中心点设备添加成功了!那么现在该为线的另一点添加绿色球设备,并且让绿色球设备可以被拖动。ucLine.xaml代码中需要添加一句:

< Image x:Name = " green "  Source = " green.png "  Width = " 44 "  Canvas.ZIndex = " 300 "  Height = " 44 " ></ Image >
        ucLine控件的代码页主要是为绿色球添加拖动控件,在拖动的过程中,也要让线的结尾点坐标跟随到拖动的绿色球位置。其ucLine.xaml.cs代码修改如下:
复制代码
public   partial   class  ucLine : UserControl
{
public  ucLine()
{
InitializeComponent();
dragBehavior.Attach(
this .green);
dragBehavior.Dragging 
+=   new  MouseEventHandler(dragBehavior_Dragging);
}
MouseDragElementBehavior dragBehavior 
=   new  MouseDragElementBehavior();
private   double  _R;
private   double  _AngleAll;
private   double  _centerX;
private   double  _centerY;

///   <summary>
///  中心圆半径
///   </summary>
public   double  R
{
get  {  return  _R; }
set  { _R  =  value; }
}
private   double  _X2;
private   double  _Y2;
///   <summary>
///  指定本控件的X2坐标
///   </summary>
public   double  X2
{
get  {  return  _X2; }
set
{
_X2 
=  value;
this .LineD.X2  =   this .X2;
}
}
///   <summary>
///  指定本控件的Y2坐标
///   </summary>
public   double  Y2
{
get  {  return  _Y2; }
set
{
_Y2 
=  value;
this .LineD.Y2  =   this .Y2;
}
}
///   <summary>
///  本控件的中心原点X坐标
///   </summary>
public   double  CenterX
{
get  {  return  _centerX; }
set
{
_centerX 
=  value;
this .LineD.X1  =  _centerX;
}
}
///   <summary>
///  本控件的中心原点Y坐标
///   </summary>
public   double  CenterY
{
get  {  return  _centerY; }
set
{
_centerY 
=  value;
this .LineD.Y1  =  _centerY;
}
}
///   <summary>
///  本控件的起始线弧度
///   </summary>
public   double  AngleAll
{
get  {  return  _AngleAll; }
set
{
_AngleAll 
=  value;
// 计算得到角度,然后复制给线的终点坐标位置。注意:设置线终点坐标时须加入线的起点位置
double  sinAngle  =  Math.Sin( this .AngleAll  *  Math.PI  /   180 );
double  cosAngle  =  Math.Cos( this .AngleAll  *  Math.PI  /   180 );
this .LineD.X2  =  cosAngle  *   this .R  +   this .CenterX;
this .LineD.Y2  =   this .CenterY  -  sinAngle  *   this .R;
// 设置绿色球的坐标位置。
this .green.SetValue(Canvas.LeftProperty,  this .LineD.X2  -   22 );
this .green.SetValue(Canvas.TopProperty,  this .LineD.Y2  -   22 );
}
}
///   <summary>
///  green被拖动的时候触发的事件
///   </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 ;
// 设置本条线的结尾点坐标为拖动后的坐标
this .LineD.X2  =  x1;
this .LineD.Y2  =  y1;
}
}
复制代码

        现在所有的动画已经完成,本实例采用VS2010+Silverlight编写,点击 SLLineForYell.rar 下载实例源码:


    本文转自程兴亮博客园博客,原文链接:http://www.cnblogs.com/chengxingliang/archive/2011/03/02/1968832.html,如需转载请自行联系原作者


相关文章
Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象
原文:Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象 原创文章,如需转载,请注明出处。   最近在一直研究Silverlight下的数据绑定控件,发现有这样两个接口IEditableObject 和IEditableCollectionView,记录一下结论,欢迎交流指正。
870 0

热门文章

最新文章