找回密码
 立即注册

QQ登录

只需一步,快速开始

WPF_guy

论坛元老

6

主题

23

帖子

9326

积分

论坛元老

积分
9326

活字格认证微信认证勋章元老葡萄

WPF_guy
论坛元老   /  发表于:2013-4-25 15:51  /   查看:6950  /  回复:2
在使用C1Gauge控件时积累一些很有用的经验,在这里可以和大家分享一下。主要是两个方面:

一、自定义C1Gauge控件的外观。
    默认的Gauge控件外观无法满足高用户体验的需求,因此需要自定义控件的外观。
(1)对仪器表盘外观的自定义
在XAML中,通过对Gauge控件的FaceTemplate属性进行编写,可以做到很多有价值的效果,如:修改仪器表盘的形状、使整体美观等。
在代码的实现上,可以参照ComponentOne的官方DEMO中的Speedometers,其中包含的FaceTemplate的用法值得借鉴。
在此贴出其中使用FaceTemplate的代码段给大家分享一下:
  1. <c1:C1RadialGauge.FaceTemplate>
  2.             <DataTemplate>
  3.                 <Grid>
  4.                     <Grid.RowDefinitions>
  5.                         <RowDefinition Height="0.03*" />
  6.                         <RowDefinition Height="0.02*" />
  7.                         <RowDefinition Height="0.848*" />
  8.                         <RowDefinition Height="0.072*" />
  9.                         <RowDefinition Height="0.03*" />
  10.                     </Grid.RowDefinitions>
  11.                     <Grid.ColumnDefinitions>
  12.                         <ColumnDefinition Width="0.032*" />
  13.                         <ColumnDefinition Width="0.018*" />
  14.                         <ColumnDefinition Width="0.867*" />
  15.                         <ColumnDefinition Width="0.05*" />
  16.                         <ColumnDefinition Width="0.033*" />
  17.                     </Grid.ColumnDefinitions>
  18.                     <Path Stretch="Uniform" Stroke="#FF8D8D8D" Data="M371.66751,0.5 C398.54837,98.324493 406.9313,186.78342 391.16183,284.59363 C405.31677,305.35202 415.47299,351.00616 386.32697,380.46704 C359.79633,407.28427 319.9631,403.50571 292.96335,390.98608 C195.27484,406.7576 98.225914,399.52081 0.52357554,371.66711 C0.50038487,371.35764 0.50000364,371.0484 0.5,370.73914 C0.50000364,166.55817 166.59108,0.97830737 371.66751,0.5 z" Grid.ColumnSpan="5" Grid.RowSpan="5">
  19.                         <Path.Fill>
  20.                             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  21.                                 <GradientStop Color="#FFA0A0A0" />
  22.                                 <GradientStop Color="#FFFFFFFF" Offset="0.799" />
  23.                                 <GradientStop Color="#FFC4C4C4" Offset="1" />
  24.                             </LinearGradientBrush>
  25.                         </Path.Fill>
  26.                     </Path>
  27.                     <Path Stretch="Uniform" Stroke="#FF8D8D8D" Data="M371.66751,-0.88071233 C398.54837,96.943787 404.33206,192.68999 388.56259,290.50061 C400.33197,307.50589 414.90622,349.21121 388.24902,378.96298 C361.45685,408.86542 315.66614,395.47595 298.66266,388.61816 C200.97397,404.38968 95.764549,398.90549 -1.9378005,371.05179 C-1.9609913,370.74231 -2.261415,370.75574 -2.2614188,370.44647 C-1.091743,272.38522 39.302441,180.92236 105.74311,113.2928 C176.39317,41.378529 275.98953,-3.5868359 371.66751,-0.88071233 z" Grid.Column="1" Grid.Row="1" Grid.RowSpan="3" Grid.ColumnSpan="3">
  28.                         <Path.Fill>
  29.                             <RadialGradientBrush>
  30.                                 <RadialGradientBrush.RelativeTransform>
  31.                                     <TransformGroup>
  32.                                         <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleY="1.439" ScaleX="1.469" />
  33.                                         <SkewTransform CenterX="0.5" CenterY="0.5" />
  34.                                         <RotateTransform CenterX="0.5" CenterY="0.5" />
  35.                                         <TranslateTransform Y="0.327" X="0.338" />
  36.                                     </TransformGroup>
  37.                                 </RadialGradientBrush.RelativeTransform>
  38.                                 <GradientStop Color="#FF2E3B51" Offset="0.009" />
  39.                                 <GradientStop Color="#FF040E1F" Offset="1" />
  40.                             </RadialGradientBrush>
  41.                         </Path.Fill>
  42.                     </Path>
  43.                     <Path Data="M339.83496,400.3598 C338.22495,384.3598 350.2038,296.3598 414.20099,232.35982 C463.99948,176 538.63409,153.43927 587.95782,153.43927 C593.4881,177.30829 597.28088,195.27232 598.47644,208 C598.47644,208 487.99896,191.99997 416.00192,264 C347.8858,332.11899 339.83496,400.3598 339.83496,400.3598 z" Fill="#19FFFFFF" Stretch="Uniform" Grid.Column="2" Grid.Row="2" />
  44.                 </Grid>
  45.             </DataTemplate>
  46.         </c1:C1RadialGauge.FaceTemplate>
复制代码


参照上述例子,我们可以画出很多有创意的仪器来哦~~

(2)自定义指针形状
这个问题的解决方法在纠结了好几天之后终于搞定了。方法是:在静态资源中建立一个Style用于编辑指针形状,再在定义的Gauge标签中的PointerStyle属性赋值为资源中的那个Style即可。
分享个实例:
先在静态资源中编辑如下代码:
  1.             <Style x:Key="Pointer" TargetType="{x:Type c1:C1GaugePointer}">
  2.                 <Setter Property="Template">
  3.                         <Setter.Value>
  4.                                 <ControlTemplate TargetType="{x:Type c1:C1GaugePointer}">
  5.                         <Path  x:Name="Root" Stretch="Fill" Fill="Red" Stroke="Red" Data="M278.25,-26.5 L277.75,80 271.5,159.5 271.5,239.5 C271.5,279.5 271.5,311.5 271.5,359.5 271.5,423.5 270.66667,412.83333 268,439.5 L294.5,439.5 C291.83333,412.83333 290,423.5 290,359.5 290,319.5 287.5,279.5 288.5,239.5 L287.5,159.5 280.75,80 280.25,-26.5 z" />
  6.                     </ControlTemplate>
  7.                         </Setter.Value>
  8.                 </Setter>
  9.         </Style>
复制代码

再在定义的Gauge控件中如下赋值:
<c1:C1RadialGauge  HorizontalAlignment="Left" x:Name="c1RadialGauge1" VerticalAlignment="Top"  PointerStyle="{StaticResource ResourceKey=Pointer}"  PointerWidth="0.03" PointerLength="0.6" PointerOffset="-.2" >

这样我们就能加入自己绘制的仪表指针~~

二、实现C1RadialGauge仪表的动画效果
对线性仪表的动画效果可以通过参考官方DEMO就能做出来。而对于RadialGauge,我还没找到过其随用户数据变化而产生动画效果的例子。在此分享一下我的经验供大家交流。
我要实现的目标是:用一个Timer每一秒产生一个随机数,而仪表能够随着数据移动指针,并实现指针移动时的动画。
解决思路是:自定义一个类,用于存储两个数据:指针偏转前的数据值和需要偏转到的目标数据值。在每次产生新数据时触发的函数中启动动画效果函数,实现指针的移动。

以下是我的整个实现代码,希望高手批评指正。
XAML代码:
  1. <Window
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="Gauge5.MainWindow"
  5.         Title="MainWindow" Height="700" Width="600" Background="Black">
  6.     <Window.Resources>
  7.         <Storyboard x:Key="story1" Storyboard.TargetName="c1RadialGauge1" Storyboard.TargetProperty="(c1:C1RadialGauge.Value)"/>
  8.             <Style x:Key="Pointer" TargetType="{x:Type c1:C1GaugePointer}">
  9.                 <Setter Property="Template">
  10.                         <Setter.Value>
  11.                                 <ControlTemplate TargetType="{x:Type c1:C1GaugePointer}">
  12.                         <Path  x:Name="Root" Stretch="Fill" Fill="Red" Stroke="Red" Data="M278.25,-26.5 L277.75,80 271.5,159.5 271.5,239.5 C271.5,279.5 271.5,311.5 271.5,359.5 271.5,423.5 270.66667,412.83333 268,439.5 L294.5,439.5 C291.83333,412.83333 290,423.5 290,359.5 290,319.5 287.5,279.5 288.5,239.5 L287.5,159.5 280.75,80 280.25,-26.5 z" />
  13.                     </ControlTemplate>
  14.                         </Setter.Value>
  15.                 </Setter>
  16.         </Style>
  17.         <DataTemplate x:Key="MarkSmall">
  18.             <Rectangle Height="4" Width="0.8" VerticalAlignment="Bottom"
  19.                                         Fill="Wheat" Stretch="Fill" StrokeThickness="1" >
  20.             </Rectangle>
  21.         </DataTemplate>

  22.         <DataTemplate x:Key="MarkBig">
  23.             <Rectangle Height="8" Width="0.5" VerticalAlignment="Bottom"
  24.                                         Fill="Wheat" Stretch="Fill" StrokeThickness="0" />
  25.         </DataTemplate>
  26.     </Window.Resources>
  27.     <Grid  Background="Black" Margin="30">
  28.             <c1:C1RadialGauge  HorizontalAlignment="Left" x:Name="c1RadialGauge1" VerticalAlignment="Top"
  29.                            StartAngle="-135" SweepAngle="270" Minimum="0" Maximum="200" PointerStyle="{StaticResource ResourceKey=Pointer}"
  30.                            PointerWidth="0.03" PointerLength="0.6" PointerOffset="-.2" Grid.RowSpan="3" Grid.ColumnSpan="2" PointerCapStroke="Red"
  31.                            Background="Transparent" BorderBrush="White" BorderThickness="20" >
  32.                 <c1:C1RadialGauge.PointerCapFill>
  33.                     <RadialGradientBrush>
  34.                         <GradientStop Color="#FF232F43" Offset="0"/>
  35.                         <GradientStop Color="#FFEF0A0A" Offset="1"/>
  36.                         <GradientStop Color="#FFFA0000" Offset="0.737"/>
  37.                         <GradientStop Color="#FF091425" Offset="0.703"/>
  38.                     </RadialGradientBrush>
  39.                 </c1:C1RadialGauge.PointerCapFill>
  40.                 <c1:C1RadialGauge.FaceTemplate>
  41.                     <DataTemplate>
  42.                         <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
  43.                             <Grid.ColumnDefinitions>
  44.                                 <ColumnDefinition Width="0.04*"/>
  45.                                 <ColumnDefinition Width="0.92*"/>
  46.                                 <ColumnDefinition Width="0.04*"/>
  47.                             </Grid.ColumnDefinitions>
  48.                             <Grid.RowDefinitions>
  49.                                 <RowDefinition Height="0.04*"/>
  50.                                 <RowDefinition Height="0.92*"/>
  51.                                 <RowDefinition Height="0.04*"/>
  52.                             </Grid.RowDefinitions>
  53.                             <Path   Grid.ColumnSpan="3" Grid.RowSpan="3" Stretch="Uniform" Data="F1 M 240.5,0.5C 373.048,0.5 480.5,107.952 480.5,240.5C 480.5,373.048 373.048,480.5 240.5,480.5C 107.952,480.5 0.5,373.048 0.5,240.5C 0.5,107.952 107.952,0.5 240.5,0.5 Z">
  54.                                 <Path.Fill>
  55.                                     <RadialGradientBrush>
  56.                                         <GradientStop Color="#FF0E161F" Offset="0"/>
  57.                                         <GradientStop Color="#FF0E161F" Offset="0.267"/>
  58.                                     <GradientStop Color="#FF2286FA" Offset="0.27"/>
  59.                                         <GradientStop Color="#FF0E161F" Offset="0.353"/>
  60.                                         <GradientStop Color="#FF0E161F" Offset="1"/>
  61.                                     </RadialGradientBrush>
  62.                                 </Path.Fill>
  63.                             </Path>
  64.                             <Path Grid.ColumnSpan="3" Grid.RowSpan="3" Stretch="Uniform" Fill="White" Data="M 250.5,0.5C 388.571,0.5 500.5,112.429 500.5,250.5C 500.5,388.571 388.571,500.5 250.5,500.5C 112.429,500.5 0.500015,388.571 0.500015,250.5C 0.500015,112.429 112.429,0.5 250.5,0.5 Z M 250.5,5.49994C 385.81,5.49994 495.5,115.19 495.5,250.5C 495.5,385.81 385.81,495.5 250.5,495.5C 115.19,495.5 5.50002,385.81 5.50002,250.5C 5.50002,115.19 115.19,5.49994 250.5,5.49994 Z" StrokeThickness="0" >
  65.                                 <Path.Effect>
  66.                                     <BlurEffect/>
  67.                                 </Path.Effect>
  68.                             </Path>
  69.                         </Grid>
  70.                     </DataTemplate>
  71.                 </c1:C1RadialGauge.FaceTemplate>
  72.                 <c1:C1GaugeLabel From="0" To="200" Interval="20" Location="0.95" FontSize="18" FontWeight="UltraBlack" Foreground="Wheat"/>
  73.                 <c1:C1GaugeMark From="0" To="200" Interval="10" Location="1.05" Template="{StaticResource MarkBig}" />
  74.                 <c1:C1GaugeMark From="0" To="200" Interval="2.5" Location="1.075" Template="{StaticResource MarkSmall}"/>
  75.             </c1:C1RadialGauge>
  76.         </Grid>   
  77. </Window>
复制代码


C#代码:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14. using System.Windows.Threading;
  15. using System.ComponentModel;
  16. using System.Windows.Media.Animation;

  17. namespace Gauge5
  18. {
  19.     /// <summary>
  20.     /// MainWindow.xaml 的交互逻辑
  21.     /// </summary>
  22.     public partial class MainWindow : Window
  23.     {
  24.         DispatcherTimer dt;
  25.         Random rnd = new Random();
  26.         public Data data1 = new Data();
  27.         double range;

  28.         public MainWindow()
  29.         {
  30.             InitializeComponent();
  31.             //添加一个定时器,每秒产生一个数据
  32.             range = c1RadialGauge1.SweepAngle;
  33.             dt = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };
  34.             dt.Tick += (s, e) => getData();
  35.             dt.Start();
  36.         }
  37.         public void getData()
  38.         {   //产生的数据存入Data类的data1实例中
  39.             double r = range * rnd.NextDouble();
  40.             data1.DATA_former = data1.DATA_later;
  41.             data1.DATA_later = r;
  42.             Storyboard st = (Storyboard)this.FindResource("story1");
  43.             DoubleAnimation da = new DoubleAnimation() { From = data1.DATA_former, To = data1.DATA_later, Duration = new TimeSpan(0,0,0,0,500) };
  44.             st.Children.Add(da);
  45.             this.BeginStoryboard(st);
  46.         }
  47.     }
  48.     public class Data
  49.     {
  50.         public double DATA_former { get; set; }
  51.         public double DATA_later { get; set; }
  52.     }
  53. }
复制代码


如果有什么问题或建议,希望能多多讨论哈~~


最后附上实现效果的视频:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

2 个回复

倒序浏览
ZenosZeng讲师达人认证 悬赏达人认证
超级版主   /  发表于:2013-4-25 16:26:00
沙发

太棒了,加勋章
回复 使用道具 举报
WPF_guy
论坛元老   /  发表于:2013-4-25 16:37:00
板凳
回复 2楼dof的帖子

谢谢哈!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部