Создание раскадровки в коде позади в WPF

Следующий код работает нормально.

<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Duration="0:0:.8" Storyboard.TargetProperty="Left" From="1920" To="0" AccelerationRatio=".1"/>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</Window.Triggers>

Но в этом случае значения From и To являются статическими. Мне нужно передать значения динамического системного разрешения. Поэтому мне нужно, чтобы он был создан в коде позади. Можно ли сделать?

Как преобразовать его в программный код?


person Raj    schedule 09.04.2013    source источник
comment
Да, вы можете создать объект Storyboard в коде и применить те же свойства, что и в XAML. Все может быть заполнено динамически на основе полученного ввода.   -  person Terry    schedule 09.04.2013
comment
Пробовали ли вы искать, в Интернете есть множество примеров (пример: codeproject.com/Articles/23257/)   -  person Terry    schedule 09.04.2013
comment
да, тот же пример, который я прошел. попробуйте эту раскадровку sb = new Storyboard(); DoubleAnimation da_AngleAnimation = new DoubleAnimation(); Длительность = новая длительность (TimeSpan.FromSeconds (1)); da_AngleAnimation.Duration = продолжительность; da_AngleAnimation.From = 1920; da_AngleAnimation.To = 100; sb.Duration = продолжительность; sb.BeginAnimation(Window.LeftProperty, da_AngleAnimation); Это не работает. я где-то ошибся?   -  person Raj    schedule 09.04.2013
comment
ваша раскадровка ни к чему не подключена, я думаю, это может быть проблемой. Кроме того, чего вы пытаетесь достичь, если вы просто хотите запустить анимацию и не повторять, вам не нужна раскадровка объекта, вы можете просто использовать анимацию, которая может быть запущена на объекте, который вы хотите анимировать ( посмотри мой ответ).   -  person Terry    schedule 09.04.2013


Ответы (3)


При работе с кодом вам на самом деле не нужна раскадровка, просто анимация для основных вещей, как вы показываете в своем вопросе. Я сделал небольшой пример, чтобы показать, как просто это работает.

Это полный код главного окна:

namespace WpfCSharpSandbox
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            WidenObject(150, TimeSpan.FromSeconds(1));
        }

        private void WidenObject(int newWidth, TimeSpan duration)
        {
            DoubleAnimation animation = new DoubleAnimation(newWidth, duration);
            rctMovingObject.BeginAnimation(Rectangle.WidthProperty, animation);
        }
    }
}

Вот как выглядит XAML:

<Window x:Class="WpfCSharpSandbox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Sandbox" Height="350" Width="525">
    <Grid Background="#333333">
        <Rectangle x:Name="rctMovingObject" Fill="LimeGreen" Width="50" Height="50"/>
    </Grid>
</Window>

Поместите это в приложение WPF и посмотрите, как оно работает, поэкспериментируйте с ним и попробуйте другие анимации/свойства.

person Terry    schedule 09.04.2013
comment
Я попробовал это вместо прямоугольника DoubleAnimation animation = new DoubleAnimation (1920, 100, продолжительность); page.BeginAnimation(Window.LeftProperty, анимация); Он отлично работает в соответствии с моим требованием - person Raj; 09.04.2013
comment
Я просто предполагаю, что анимация, которую вы подключили к своей раскадровке, не была вызвана должным образом, но, поместив ее в окно, она работает. - person Terry; 09.04.2013
comment
Я хочу остановить анимацию вручную, поэтому требуется использование раскадровки :( - person M.kazem Akhgary; 22.01.2017
comment
Вопрос для раскадровки, так что это не ответ - person Luca Ziegler; 11.06.2019
comment
Как это принятый ответ? OP хочет знать, как сделать раскадровку в коде программной части, и ответ (в классическом стиле SO) вам не нужно делать «это», вместо этого делайте «это». Круто, но я хочу научиться делать «это», отсюда и вопрос, конкретно спрашивая об «ЭТОМ». - person AsPas; 22.06.2021

Добавление примера кода комментария djerry будет выглядеть так:

var anim = new DoubleAnimation {
                                From = 1920, 
                                To = 1, 
                               };

wnd.BeginAnimation(Window.LeftProperty, anim); 

и вам нужно будет иметь этот код в обработчике событий, загруженных окном. Надеюсь это поможет.

person Suresh    schedule 09.04.2013
comment
Вопрос для раскадровки, так что это не ответ - person Luca Ziegler; 11.06.2019
comment
В заголовке вопроса OP говорится о раскадровке, но на самом деле вопрос был о том, как он может динамически устанавливать значения From и To в своей анимации из кода программной части. Ответ касается этого. - person Suresh; 11.06.2019

Пример кода вопроса касался анимации свойства Window.Left, и я искал именно этот случай, но данный ответ работает только для одноразового варианта использования.
В частности: если анимация была выполнена, а окно затем перемещается вручную с помощью перетаскивания, та же процедура анимации не будет работать снова, как хотелось бы. Анимация всегда будет использовать конечные координаты последнего запуска анимации.
Поэтому, если вы переместите окно, оно отскочит назад перед запуском новой анимации:

https://imgur.com/a/hxRCqm7

Чтобы решить эту проблему, необходимо удалить все AnimationClock из анимированного свойства после завершения анимации.

Это делается с помощью ApplyAnimationClock или BeginAnimation с null в качестве второго параметра:

public partial class MainWindow : Window
{
    // [...]

    private void ButtonMove_Click(object sender, RoutedEventArgs e)
    {
        AnimateWindowLeft(500, TimeSpan.FromSeconds(1));
    }

    private void AnimateWindowLeft(double newLeft, TimeSpan duration)
    {
        DoubleAnimation animation = new DoubleAnimation(newLeft, duration);
        myWindow.Completed += AnimateLeft_Completed;
        myWindow.BeginAnimation(Window.LeftProperty, animation);
    }

    private void AnimateLeft_Completed(object sender, EventArgs e)
    {
        myWindow.BeginAnimation(Window.LeftProperty, null);
        // or
        // myWindow.ApplyAnimationClock(Window.LeftProperty, null);
    }
}

XAML:

<Window x:Class="WpfAppAnimatedWindowMove.MainWindow"
        // [...]
        Name="myWindow">

Результат:
https://imgur.com/a/OZEsP6t

См. также раздел Примечания в Microsoft Docs — Перечисление HandoffBehavior

person Martin Schneider    schedule 26.11.2019