当故事板动画时,为什么设置属性上的函数不会更新

时间:2012-05-25 01:23:24

标签: c# wpf animation binding inotifypropertychanged

我有财产:

    double _X;
    public double X
    {
        get {
            this.Title = _X.ToString();
            return _X; 
        }
        set { 
            _X = value;
            this.Title = _X.ToString(); // !!!! this line does not execute when property changes from storyboard
            RaisePropertyChanged("X"); }
    }

和控件:

   <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Height="99.2" Margin="37,14,0,0" VerticalAlignment="Top" Width="98.4" RenderTransformOrigin="0.5,0.5">
        <Button.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
            </TransformGroup>
        </Button.RenderTransform>
    </Button>

故事板:

<Storyboard x:Key="Storyboard1" AutoReverse="True" FillBehavior="HoldEnd">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="button">
            <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="100">
                <EasingDoubleKeyFrame.EasingFunction>
                    <CircleEase EasingMode="EaseOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>

</Storyboard>

当我为属性设置动画时,如果我实现INotifyPropertyChanged接口,为什么set方法不会改变?换句话说为什么行this.Title = _X.ToString();不执行同时动画故事板。每次故事板动画时,如何更新X属性?


修改

我忘了提到我需要这个功能的原因。我经常需要为不属于xaml的属性设置动画。例如,假设我想为主音量或鼠标位置设置动画。我知道我可以创建一个线程,然后进行数学运算并创建自己的动画。但是如果wpf已经有几个缓动功能和动画,为什么要重新发明轮子。如果我可以使用expresion blend创建一个故事板,然后使用该故事板为我后面的代码中的属性设置动画,那将会很不错。


EDIT2

根据@clemens我已经解决了这个问题(也许我做错了):

我上课了:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows;

namespace SomeNamespace
{
    public partial class MyUserControl : UserControl, INotifyPropertyChanged
    {


        public static readonly DependencyProperty SomeDoubleProperty =
    DependencyProperty.Register("SomeDouble", typeof(Double),
        typeof(MyUserControl), new PropertyMetadata(0.0));


        public double SomeDouble
        {
            get
            {
                return (double)GetValue(SomeDoubleProperty);

            }
            set
            {
                SetValue(SomeDoubleProperty, value);
                MessageBox.Show("this msg should appear meanwhile animating!");
                // code does not execute
                RaisePropertyChanged("SomeDouble");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }




    }
}

我有观点

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:test="clr-namespace:SomeNamespace"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Window.Resources>
        <Storyboard x:Key="Storyboard1"  >
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="SomeDouble" Storyboard.TargetName="m">
                <EasingDoubleKeyFrame KeyTime="0:0:5.4" Value="100">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <CircleEase EasingMode="EaseOut"/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>            
        </Storyboard>
    </Window.Resources>
    <Grid>
        <test:MyUserControl x:Name="m" SomeDouble="5"></test:MyUserControl>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="311,50,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />

    </Grid>
</Window>

后面的按钮代码启动故事板......

该属性在代码背后没有改变,同时为其设置动画......

1 个答案:

答案 0 :(得分:4)

如果我理解你的话,那么你将为TranslateTransform的X属性设置动画,该属性也绑定到你的X属性(你没有提到它的类别)定义的)。

即使你已经双向声明了绑定,你的方法也行不通。诸如TranslateTransform.X之类的dependency property从各种提供程序中获取其值,例如样式设置器,触发器,动画,值继承,属性元数据的默认值,本地值等等(数据绑定设置的地方)本地价值)。这些提供商按特定顺序应用,即具有特定precedence

在您的方案中,这意味着RenderTransform.X从数据绑定中获取其本地值。启动动画时,有效属性值来自该动画,只要它正在运行或保持该值。同时,属性的本地值不会改变,这意味着对绑定没有影响(即使它是双向的)。

如果您想为X媒体资源制作动画,可以将其设为custom dependency property并直接为其制作动画。