实际项目中,我们模拟一个监控多台电脑的雷达扫描图效果。我们假设发现了很多台设备,这些设备具有CPU使用率这个属性,在雷达扫描的时候,如果CPU的值高于90则报警为红色。

        本节实例建立在上一节的基础之上,在本节中我们将向雷达扫描图中随机投放多台设备点,这些点拥有X坐标和Y坐标的属性以设置它在雷达扫描图中的位置,并且有一个闪动的动画效果。新建一个自定义控件命名为Device.xaml。

        第一步计算设备的X、Y坐标设置CPU的信号值Value。在这里使用Random对象rom.Next(Math.Sin(45)*250)函数来随机 得到设备的X坐标和Y坐标,暂时先以(0,0)点为中心坐标的250半径的圆圈范围内,这台设备在一个坐标系中还有可能出现X或者Y坐标出现负的情况,这 个时候我们可以调用Random随机对象的随机小于2的数,如果为1的话就将随机得到的数设置为负。(注意:Random对象是使用系统时钟生成其种子值 的,所以在全局范围内不能出现多个Random对象,否则的话你设置多个Random对象在同一个时间段内时得到的值相同的。解决方法是设置一个 public static的全局随机对象,每次要使用的时候直接调用这个对象的Next()函数即可。)计算出了X、Y坐标之后此时的中心点是按照(0,0)点位置的 坐标,在本项目中的中心点的位置是(300,300),所以X坐标加300,Y坐标加300。另外使用随机对象随机了100以内的数字赋值给本设备的 CPU使用率信号值Value,下面请看代码:

 

  1. public Device() 
  2. InitializeComponent(); 
  3. InitData(); 
  4.  
  5. private double _X; 
  6. private double _Y; 
  7. private double _Value; 
  8. /// <summary> 
  9. /// X轴坐标 
  10. /// </summary> 
  11. public double X 
  12. get { return _X; } 
  13. set { _X = value; } 
  14.  
  15. /// <summary> 
  16. /// Y轴坐标 
  17. /// </summary> 
  18. public double Y 
  19. get { return _Y; } 
  20. set { _Y = value; } 
  21. /// <summary> 
  22. /// 设备关键信号值 
  23. /// </summary> 
  24. public double Value 
  25. get { return _Value; } 
  26. set { _Value = value; } 
  27. public static Random rom = new Random(); 
  28. public void InitData() 
  29. #region 随机将设备分布到雷达图中,模拟扫描到的机器 
  30. //模拟设备CPU值 
  31. Value = rom.Next(100); 
  32. //首先模拟设备,让设备随机分布在图中。 
  33. //模拟设备X坐标 
  34. X = rom.Next(200); 
  35. //模拟X坐标的符号,如果为0则为正,如果为1则为负; 
  36. int Xmark = rom.Next(2); 
  37. if (Xmark == 1) 
  38. X = -X; 
  39. X = X + 300.0; 
  40.  
  41. //模拟设备Y坐标 
  42. Y = rom.Next(Convert.ToInt32(Math.Sin(45)*250)); 
  43. //模拟Y坐标的符号,如果为0则为正,如果为1则为负; 
  44. int Ymark = rom.Next(2); 
  45. if (Ymark == 1) 
  46. Y = -Y; 
  47. Y = Y + 300.0; 
  48. Storyboard1.Begin(); 
  49. #endregion 
  50. //tip显示当前值 
  51. devicetip.Content = "设备CPU占用率:" + Value + "--X:" + X + "--Y:" + Y; 

        第二步开始制作设备点的动画效果,在Device.xaml中我们添加两个一摸一样的矩形框(RectangleRed、Rectangleblue), 这两个矩形框是通过CompositeTransform复合变形和渐变得到一个中心白色,外层渐变透明的小圆圈,我们控制RectangleRed小圆 圈的ScaleX和,ScaleY在1秒内从0.3倍变到2倍,同时控制Rectangleblue小圆圈的ScaleX和,ScaleY在1秒内从2倍 变到0.3倍。这样就得到了一个一直闪动的点,下面请看Xaml代码:

 

  1. <UserControl.Resources> 
  2. <Storyboard x:Name="Storyboard1" RepeatBehavior="Forever"
  3. <DoubleAnimation Duration="0:0:1" From="0.3" To="2" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="RectangleRed" /> 
  4. <DoubleAnimation Duration="0:0:1" From="0.3" To="2" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="RectangleRed" /> 
  5. <DoubleAnimation Duration="0:0:1" From="2" To="0.3" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="Rectangleblue" /> 
  6. <DoubleAnimation Duration="0:0:1" From="2" To="0.3" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="Rectangleblue" /> 
  7. </Storyboard> 
  8. </UserControl.Resources> 
  9. <Grid x:Name="LayoutRoot" > 
  10. <Rectangle HorizontalAlignment="Left" VerticalAlignment="Top" Height="16" x:Name="RectangleRed" RadiusX="15" RadiusY="15" Width="15" RenderTransformOrigin="0.5,0.5"
  11. <Rectangle.RenderTransform> 
  12. <CompositeTransform/> 
  13. </Rectangle.RenderTransform> 
  14. <Rectangle.Fill> 
  15. <RadialGradientBrush> 
  16. <GradientStop Color="White" Offset="0"/> 
  17. <GradientStop Color="#30FFFFFF" Offset="0.276"/> 
  18. <GradientStop Color="Transparent" Offset="0.582"/> 
  19. </RadialGradientBrush> 
  20. </Rectangle.Fill> 
  21. </Rectangle> 
  22. <Rectangle HorizontalAlignment="Left" VerticalAlignment="Top" Height="16" x:Name="Rectangleblue" RadiusX="15" RadiusY="15" Width="15" RenderTransformOrigin="0.5,0.5"
  23. <Rectangle.RenderTransform> 
  24. <CompositeTransform/> 
  25. </Rectangle.RenderTransform> 
  26. <Rectangle.Fill> 
  27. <RadialGradientBrush> 
  28. <GradientStop Color="White" Offset="0"/> 
  29. <GradientStop Color="#30FFFFFF" Offset="0.276"/> 
  30. <GradientStop Color="Transparent" Offset="0.582"/> 
  31. </RadialGradientBrush> 
  32. </Rectangle.Fill> 
  33. <ToolTipService.ToolTip> 
  34. <ToolTip x:Name="devicetip" /> 
  35. </ToolTipService.ToolTip> 
  36. </Rectangle> 
  37. </Grid> 

        最后一步我们在雷达扫描图初始化的时候创建多个扫描点投放到图中:

 

  1. #region 添加闪动的设备 
  2. for (int i = 0; i < 15; i++) 
  3. Device dev=new Device(); 
  4. //设置X、Y坐标和Z层次 
  5. dev.SetValue(Canvas.TopProperty,dev.Y); 
  6. dev.SetValue(Canvas.LeftProperty,dev.X); 
  7. dev.SetValue(Canvas.ZIndexProperty, 600); 
  8. LayoutRoot.Children.Add(dev); 
  9. #endregion 

        本节使用VS2010+Silverlight4.0编写,点击 SLRandarAddPoint.rar 下载源码,非IE6.0用户可以点击下图观看演示: