justin_amei 发表于 2016-4-28 14:44:47

Gauge控件EventTrigger如何使用ValueChanged事件?

我打算利用Gauge控件的ValueChanged事件来触发Gauge控件动画,但是不知道如何跟EventTrigger的RoutedEvent绑定,怎么写都提示报错。

下面的代码是C1给的demo程序中拷贝过来的

<c1:C1RadialGauge x:Name="gauge" PointerOrigin="0.5,0.7" StartAngle="-80" SweepAngle="160" Minimum="0" Maximum="25" BorderThickness="0" Background="Transparent" CoverVisibility="Collapsed">
            <c1:C1RadialGauge.Triggers>
                <EventTrigger RoutedEvent="c1:C1Gauge.ValueChanged">//报错
                  <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimationUsingKeyFrames RepeatBehavior="1" BeginTime="00:00:00" Duration="00:00:05" AutoReverse="True" Storyboard.TargetName="gauge" Storyboard.TargetProperty="(c1:C1Gauge.Value)">
                              <SplineDoubleKeyFrame KeyTime="00:00:05.00" Value="150" KeySpline="0,0,1,0" />
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                  </BeginStoryboard>
                </EventTrigger>
            </c1:C1RadialGauge.Triggers>


请指教如何实现上述功能,多谢!~

Alice 发表于 2016-4-28 17:12:43

使用C1RadiaGauge实现仪表的动画效果,请参考如下帖子的第二部分(随用户数据变化而产生动画效果的例子):
http://gcdn.gcpowertools.com.cn/showtopic.aspx?topicid=8748

justin_amei 发表于 2016-5-7 16:33:07

Alice 发表于 2016-4-28 17:12
使用C1RadiaGauge实现仪表的动画效果,请参考如下帖子的第二部分(随用户数据变化而产生动画效果的例子): ...

我按照例子试了,但是发现valuechanged事件会不停循环触发,不知道为什么。
不如我让value由0变为5,会触发一次valuechanged事件,执行0-5的动画。事件完成后,马上又触发valuechanged事件,执行5-0的动画。然后一直循环以上过程。而且整个过程并看不到动画效果,gauge的值在画面上一直保持0。

我在论坛搜索了C1lable的valuechanged事件也有一直触发的bug,不知道我的问题是否是一样的问题。

Alice 发表于 2016-5-10 10:49:31

justin_amei 发表于 2016-5-7 16:33
我按照例子试了,但是发现valuechanged事件会不停循环触发,不知道为什么。
不如我让value由0变为5,会 ...

把你出问题的Demo发过来,我们帮你看看。

justin_amei 发表于 2016-5-11 09:05:00

Alice 发表于 2016-5-10 10:49
把你出问题的Demo发过来,我们帮你看看。

DEMO请见附件。

Alice 发表于 2016-5-11 11:36:50

justin_amei 发表于 2016-5-11 09:05
DEMO请见附件。

问题收到,测试后给您反馈

Alice 发表于 2016-5-11 14:58:29

本帖最后由 Alice 于 2016-5-11 14:59 编辑

justin_amei 发表于 2016-5-11 09:05
DEMO请见附件。
根据你的Demo来看,通过动画修改Value的值,是会触发ValueChanged事件。
然后你的Demo中死循环调用。

为了避免死循环,那就在ValueChanged事件中加入一些判断,不要启动很多动画。一个思路,判断是否是5的倍数,如果是5的倍数,就启动动画,不是就不启动动画。

提供两个思路, 效果不一样,给你参考下。
1. ValueChanged肯定会一直触发的,因为动画是修改Value属性的。而ValueChanged事件的触发时机是Value改变。所以触发多次是正常的。至于抛exception, 原因是执行动画后,使得Value的值一直在改变,频率快于绘画的速度,所以抛Exception, 可以让动画在Dispatcher中启动。

<p>private void MachineSpeedMeter_ValueChanged(object sender, C1.WPF.PropertyChangedEventArgs<double> e)</p><p>//点击一次按钮改变Value值后,该事件循环触发
      {
            Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
            {
                var da = new DoubleAnimation(e.OldValue, e.NewValue, new TimeSpan(0, 0, 0, 2));
                var st = (Storyboard)this.FindResource("story0");
                st.Children.Add(da);
                this.BeginStoryboard(rain);
            }));
      }</p>

这样的效果是:指针一直在快速的晃动。

第二种思路:
如果想让动画从0 到 5, 然后再从5 到 0 , 然后再从0 到5 这样循环,
可以在Storyboard的Completed的事件中在启动动画,但是此时From和To是相反的。
private void St_Completed(object sender, EventArgs e)
      {
            Storyboard st = (Storyboard)this.FindResource("story0");
            var child = st.Children as DoubleAnimation;
            var da = new DoubleAnimation(child.To.Value, child.From.Value, new TimeSpan(0, 0, 0, 2));
            st.Children.Clear();
            st.Children.Add(da);
            this.BeginStoryboard(rain);
      }

在加速按钮中启动动画。

private void button_Click(object sender, RoutedEventArgs e)
      {
            //MachineSpeedMeter.Value += 5D;
            Storyboard st = (Storyboard)this.FindResource("story0");
            st.Stop();
            st.Children.Clear();
            DoubleAnimation da = new DoubleAnimation(MachineSpeedMeter.Value, MachineSpeedMeter.Value + 5D, new TimeSpan(0, 0, 0, 2));
            st.Children.Add(da);
            st.Completed += St_Completed;
            this.BeginStoryboard(rain);
      }

justin_amei 发表于 2016-5-11 16:04:50

Alice 发表于 2016-5-11 14:58
根据你的Demo来看,通过动画修改Value的值,是会触发ValueChanged事件。
然后你的Demo中死循环调用。

...

感谢版主这么详细的解答。:handshake

另外,今天我跟同事深入讨论了这个问题,找到一个解决办法。就是采用两个C1Gauge,一个在XAML前台,一个在C#后台。按钮事件对后台的Gauge的Value进行赋值,激发后台Gauge的ValueChanged事件。在后台Gauge的ValueChanged事件中,对前台的Gauge的Value进行动画操作,即可完美解决这个问题。

附上代码仅供参考。谢谢版主的热心帮助。

Alice 发表于 2016-5-11 17:10:09

justin_amei 发表于 2016-5-11 16:04
感谢版主这么详细的解答。

另外,今天我跟同事深入讨论了这个问题,找到一个解决办法。就是 ...

好的。
非常谢谢您的详细反馈。
页: [1]
查看完整版本: Gauge控件EventTrigger如何使用ValueChanged事件?