Привязка свойства «Длительность» анимации в Silverlight - PullRequest
2 голосов
/ 02 июня 2011

У меня есть DoubleAnimation, которую я хочу связать со свойствами From, To и Duration, чтобы они плавно менялись.

Привязка From и To прекрасно работает, плавно меняет их, но изменения Duration просто игнорируются.

Для отладки я сделал кнопку, которая при нажатии вызывает методы Stop и Begin содержащей StoryBoard, и анимация начиналась с начала с правильной продолжительностью. Также я проверил и увидел, что свойство Duration анимации фактически обновляется каждый раз, поэтому анимация просто игнорирует это изменение. (В отличие от «От» и «К», которые действительно реагируют плавно.)

Пробовал то же самое в WPF и получил те же результаты, вот фрагмент:

        <Canvas>
        <Canvas.Triggers>
            <EventTrigger RoutedEvent="Canvas.Loaded">
                <BeginStoryboard>
                    <Storyboard x:Name="Story">
                        <DoubleAnimation x:Name="Anime"
                                         Duration="{Binding Duration}"
                                         RepeatBehavior="Forever"
                                         Storyboard.TargetName="Text1"
                                         Storyboard.TargetProperty="(Canvas.Left)"                                             
                                         From="0"
                                         To="400"                                             
                                         />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Canvas.Triggers>
        <TextBlock Text="Hello" Name="Text1"/>
    </Canvas>

Я был бы очень признателен за объяснение, почему это не работает, и любые обходные пути, которые позволили бы привязке работать с плавным переходом.

Кроме того, фактическая моя конечная цель состоит в том, чтобы TextBlock двигался с постоянной скоростью, несмотря на изменения в From и To. Так что, если есть другой способ достичь этого, было бы еще лучше.

Спасибо.

Ответы [ 2 ]

1 голос
/ 02 июня 2011

Есть две проблемы: как написан ваш источник привязки (ViewModel), и обновили ли вы ваш текст данных. Вот мой код, и он работает.

MainPage.xaml:

<Canvas>
    <Canvas.Triggers>
        <EventTrigger RoutedEvent="Canvas.Loaded">
            <BeginStoryboard>
                <Storyboard x:Name="Story">
                    <DoubleAnimation x:Name="Anime"
                                     Duration="{Binding}"
                                     RepeatBehavior="Forever"
                                     Storyboard.TargetName="Text1"
                                     Storyboard.TargetProperty="(Canvas.Left)"                                             
                                     From="0"
                                     To="400"                                             
                                     />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Canvas.Triggers>
    <TextBlock Text="Hello" Name="Text1"/>
    <Button Content="Change" Margin="0, 100, 0, 0" Click="Button_Click" />
</Canvas>

MainPage.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace SilverlightApplication
{
    public partial class MainPage : UserControl
    {
        AnimVM vm = new AnimVM();
        double dur = 5;

        public MainPage()
        {
            InitializeComponent();

            vm.Duration = new Duration(TimeSpan.FromSeconds(dur));

            this.DataContext = vm.Duration;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            dur += 5;
            vm.Duration = new Duration(TimeSpan.FromSeconds(dur));
            this.DataContext = vm.Duration; // don't forget this line
        }
    }

    public class ViewModelBase : INotifyPropertyChanged, IDisposable
    {
        protected ViewModelBase()
        {
        }

        protected virtual bool ThrowOnInvalidPropertyName { get; private set; }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            //this.VerifyPropertyName(propertyName);

            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }

        public void Dispose()
        {
            this.OnDispose();
        }

        protected virtual void OnDispose()
        {
        }
    }

    public class AnimVM : ViewModelBase
    {
        private Duration _duration = new Duration(TimeSpan.FromSeconds(5));
        public Duration Duration
        {
            get { return _duration; }
            set
            {
                if (object.ReferenceEquals(this._duration, value)) return;

                this._duration = value;
                base.OnPropertyChanged("Duration");
            }
        }
    }
}
0 голосов
/ 25 марта 2014

Я знаю, что опаздываю на вечеринку, но проблема в том, что Duration не является DependencyProperty, поэтому WPF не прослушивает событие изменения значения и, следовательно, не обновляет анимацию при изменении значения - что отличается просто сохраняя обновленное значение в объекте.

...