Эффект затухания текста в WPF - PullRequest
6 голосов
/ 12 августа 2009

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

Я успешно выполнил половину этой работы, код ниже реагирует на событие изменения текста, немедленно делает текст невидимым, а затем исчезает в течение 3 секунд.

Подобным же образом легко выгнать текст, я просто изменяю свойства тега From и To. НО - проблема в том, что текст на экране меняется сразу. Конечно, это обычно абсолютно необходимо, но в этом случае я хочу, чтобы старый текст исчез, а затем новый текст.

Есть ли хитрый трюк для этого в анимации WPF?

Текущий недоделанный триггер:

<Style TargetType="TextBlock" x:Key="fadeinout">
        <Style.Triggers>
            <EventTrigger RoutedEvent="Binding.TargetUpdated">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:3" From="0.0" To="1.0" BeginTime="0:0:0" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Style.Triggers>
    </Style>

Ответы [ 4 ]

3 голосов
/ 21 октября 2009

Я с Фрэнсисом 1983 на этом. Я хотел бы создать новый UserControl, который на самом деле легко обрабатывает старый и новый текст с помощью fades.

Я делаю что-то похожее с меткой, которую я хочу показать только пару секунд, а затем исчезнуть. Вот что я сделал:

<Label  Name="lbl" DockPanel.Dock="Bottom" HorizontalAlignment="Center" Visibility="Collapsed">
    <Label.Style>
        <Style TargetType="{x:Type Label}">
            <Style.Triggers>
                <Trigger Property="Visibility" Value="Visible">
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:00" BeginTime="00:00:00" From="0.0" To="1.0" />
                                <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:03" BeginTime="00:00:02" From="1.0" To="0.0" />
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
    Display Text
</Label>

А затем в коде, где меняется текст метки:

//Make the label visible, starting the storyboard.
lbl.Visibility = Visibility.Visible;

DispatcherTimer t = new DispatcherTimer();
//Set the timer interval to the length of the animation.
t.Interval = new TimeSpan(0, 0, 5);
t.Tick += (EventHandler)delegate(object snd, EventArgs ea)
{
    // The animation will be over now, collapse the label.
    lbl.Visibility = Visibility.Collapsed;
    // Get rid of the timer.
    ((DispatcherTimer)snd).Stop();
};
t.Start();

Вы можете легко изменить этот пример в UserControl. Просто измените затухание в Visibility == Hidden, добавьте раскадровку, которая делает противоположность для Visibility == Visible, и измените текст и сбросьте видимость внутри обработчика Tick.

Надеюсь, это поможет!

2 голосов
/ 22 октября 2009

Вот реализация, которая автоматически выполняет постепенное исчезновение, значение переключателя, постепенное увеличение

Использовать (после установки xmlns: l в правильное пространство имен:

Label l:AnimatedSwitch.Property="Content" l:AnimatedSwitch.Binding="{Binding SomeProp}"/>

Код (это код для проверки концепции, без обработки ошибок и не готовый к производству).

public class AnimatedSwitch : DependencyObject
{
    // Define the attached properties

    public static DependencyProperty BindingProperty =
        DependencyProperty.RegisterAttached("Binding", typeof(object), typeof(AnimatedSwitch),
        new PropertyMetadata(BindingChanged));
    public static DependencyProperty PropertyProperty =
        DependencyProperty.RegisterAttached("Property", typeof(string), typeof(AnimatedSwitch));
    public static object GetBinding(DependencyObject e)
    {
        return e.GetValue(BindingProperty);
    }
    public static void SetBinding(DependencyObject e, object value)
    {
        e.SetValue(BindingProperty, value);
    }
    public static string GetProperty(DependencyObject e)
    {
        return (string)e.GetValue(PropertyProperty);
    }
    public static void SetProperty(DependencyObject e, string value)
    {
        e.SetValue(PropertyProperty, value);
    }

    // When the value changes do the fadeout-switch-fadein

    private static void BindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Storyboard fadeout = new Storyboard();
        var fadeoutAnim = new DoubleAnimation(){To=0,Duration=new Duration(TimeSpan.FromSeconds(0.3))};
        Storyboard.SetTarget(fadeoutAnim,d);
        Storyboard.SetTargetProperty(fadeoutAnim, new PropertyPath("Opacity"));
        fadeout.Children.Add(fadeoutAnim);
        fadeout.Completed += (d1, d2) =>
            {
                d.GetType().GetProperty(GetProperty(d)).SetValue(d, GetBinding(d), null);

                Storyboard fadein = new Storyboard();
                var fadeinAnim = new DoubleAnimation() { To = 1, Duration = new Duration(TimeSpan.FromSeconds(0.3)) };
                Storyboard.SetTarget(fadeinAnim, d);
                Storyboard.SetTargetProperty(fadeinAnim, new PropertyPath("Opacity"));
                fadein.Children.Add(fadeinAnim);
                fadein.Begin();
            };
        fadeout.Begin();
    }
}
1 голос
/ 12 августа 2009

Лучшим решением для этой задачи будет использование «Transition Presenter». Transition Presenter - это контейнер для вашего элемента управления (может быть TextBlock или любой другой), который реагирует на изменение содержимого, применяя назначенный переход. Вы можете выбрать один из предопределенных переходов или создать свой собственный (используя XAML). Обычно переходный докладчик использует шаблон данных для отображения связанных данных. Самый простой пример будет выглядеть так:

<lib:TransitionPresenter Transition="{StaticResource FadeTransition}
    Content="{Binding MyValue}">
    <lib:TransitionPresenter.Resources>
        <DataTemplate DataType="{x:Type System:string}">
            <TextBlock Text={Binding}/>
        </DataTemplate>
    </lib:TransitionPresenter.Resources>
</lib:TransitionPresenter>

Вот две библиотеки с исходным кодом, которые реализуют переходный презентатор:

0 голосов
/ 12 августа 2009

Я не думаю, что это возможно в решении только для XAML. TextBlock не знает о «старом» и «новом» тексте, только текст.

Я бы сделал так, чтобы создать пользовательский элемент управления, производный от TextBlock, и выполнить следующее для события TargetUpdated:

  • Вызовите раскадровку 'Fade out'
  • Изменить текст
  • Вызовите раскадровку 'Fade in'

Удачи:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...