it-swarm.com.ru

Wpf анимированный цвет фона

Мне нужна помощь в принятии правильного решения. Мне нужно анимировать цвет фона моего пользовательского элемента управления, когда происходит какое-то событие. Когда это так, я хочу изменить фон только на 1 секунду, а затем повернуть его обратно. Куда мне идти? Используйте цветную анимацию или таймер или можете каким-то другим способом.

Решаемые. Спасибо всем! Это хорошо работает для меня:

        ColorAnimation animation;
        animation = new ColorAnimation();
        animation.From = Colors.Orange;
        animation.To = Colors.Gray;
        animation.Duration = new Duration(TimeSpan.FromSeconds(1));
        this.elGrid.Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);
42
Taras

Я бы использовал EventTrigger с ColorAnimation.

В этом примере Button Brackground становится зеленым для события MouseLeave. Надеюсь, этот код похож на то, что вам может понадобиться.

<Button Content="Button" Height="75" HorizontalAlignment="Left" Margin="27,12,0,0" Name="btnImgBrush" VerticalAlignment="Top" Width="160" Background="LightGray">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.MouseLeave">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation To="Green" 
                                    Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" 
                                    FillBehavior="Stop" 
                                    Duration="0:0:1"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>
66
Klaus78

Остерегайтесь, вы можете получить System.InvalidOperationException, если ваш фон является замороженным экземпляром.

Не удается анимировать свойство «Color» для «System.Windows.Media.SolidColorBrush», поскольку объект запечатан или заморожен.

Чтобы исправить это сообщение, назначьте фон вашего элемента управления не замороженному экземпляру.

// Do not use a frozen instance
this.elGrid.Background = new SolidColorBrush(Colors.Orange);
this.elGrid.Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);

Обзор замораживаемых объектов на MSDN

25
Guish
        ColorAnimation colorChangeAnimation = new ColorAnimation();
        colorChangeAnimation.From = VariableColour;
         colorChangeAnimation.To = BaseColour;
        colorChangeAnimation.Duration = timeSpan;

        PropertyPath colorTargetPath = new PropertyPath("(Panel.Background).(SolidColorBrush.Color)");
        Storyboard CellBackgroundChangeStory = new Storyboard();
        Storyboard.SetTarget(colorChangeAnimation, BackGroundCellGrid);
        Storyboard.SetTargetProperty(colorChangeAnimation, colorTargetPath);
        CellBackgroundChangeStory.Children.Add(colorChangeAnimation);
        CellBackgroundChangeStory.Begin();

// VariableColour и BaseColour - это класс Color, timeSpan - это класс TimeSpan, BackGroundCellGrid - это класс Grid;

// нет необходимости создавать SolidColorBrush и привязку к нему в XAML; //повеселись!

6
DragonX

Вот набор прикрепленных свойств, которые можно использовать, если у вас возникнут проблемы с freezables.

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

public static class Blink
{
    public static readonly DependencyProperty WhenProperty = DependencyProperty.RegisterAttached(
        "When",
        typeof(bool?),
        typeof(Blink),
        new PropertyMetadata(false, OnWhenChanged));

    public static readonly DependencyProperty FromProperty = DependencyProperty.RegisterAttached(
        "From",
        typeof(Color),
        typeof(Blink),
        new FrameworkPropertyMetadata(Colors.Transparent, FrameworkPropertyMetadataOptions.Inherits));

    public static readonly DependencyProperty ToProperty = DependencyProperty.RegisterAttached(
        "To",
        typeof(Color),
        typeof(Blink),
        new FrameworkPropertyMetadata(Colors.Orange, FrameworkPropertyMetadataOptions.Inherits));

    public static readonly DependencyProperty PropertyProperty = DependencyProperty.RegisterAttached(
        "Property",
        typeof(DependencyProperty),
        typeof(Blink),
        new PropertyMetadata(default(DependencyProperty)));

    public static readonly DependencyProperty DurationProperty = DependencyProperty.RegisterAttached(
        "Duration",
        typeof(Duration),
        typeof(Blink),
        new PropertyMetadata(new Duration(TimeSpan.FromSeconds(1))));

    public static readonly DependencyProperty AutoReverseProperty = DependencyProperty.RegisterAttached(
        "AutoReverse",
        typeof(bool),
        typeof(Blink),
        new PropertyMetadata(true));

    public static readonly DependencyProperty RepeatBehaviorProperty = DependencyProperty.RegisterAttached(
        "RepeatBehavior",
        typeof(RepeatBehavior),
        typeof(Blink),
        new PropertyMetadata(RepeatBehavior.Forever));

    private static readonly DependencyProperty OldBrushProperty = DependencyProperty.RegisterAttached(
        "OldBrush",
        typeof(Brush),
        typeof(Blink),
        new PropertyMetadata(null));

    public static void SetWhen(this UIElement element, bool? value)
    {
        element.SetValue(WhenProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(UIElement))]
    public static bool? GetWhen(this UIElement element)
    {
        return (bool?)element.GetValue(WhenProperty);
    }

    public static void SetFrom(this DependencyObject element, Color value)
    {
        element.SetValue(FromProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(UIElement))]
    public static Color GetFrom(this DependencyObject element)
    {
        return (Color)element.GetValue(FromProperty);
    }

    public static void SetTo(this DependencyObject element, Color value)
    {
        element.SetValue(ToProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(UIElement))]
    public static Color GetTo(this DependencyObject element)
    {
        return (Color)element.GetValue(ToProperty);
    }

    public static void SetProperty(this UIElement element, DependencyProperty value)
    {
        element.SetValue(PropertyProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(UIElement))]
    public static DependencyProperty GetProperty(this UIElement element)
    {
        return (DependencyProperty)element.GetValue(PropertyProperty);
    }

    public static void SetDuration(this UIElement element, Duration value)
    {
        element.SetValue(DurationProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(UIElement))]
    public static Duration GetDuration(this UIElement element)
    {
        return (Duration)element.GetValue(DurationProperty);
    }

    public static void SetAutoReverse(this UIElement element, bool value)
    {
        element.SetValue(AutoReverseProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(UIElement))]
    public static bool GetAutoReverse(this UIElement element)
    {
        return (bool)element.GetValue(AutoReverseProperty);
    }

    public static void SetRepeatBehavior(this UIElement element, RepeatBehavior value)
    {
        element.SetValue(RepeatBehaviorProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(UIElement))]
    public static RepeatBehavior GetRepeatBehavior(this UIElement element)
    {
        return (RepeatBehavior)element.GetValue(RepeatBehaviorProperty);
    }

    private static void OnWhenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var property = GetProperty((UIElement)d) ?? GetDefaultProperty(d);
        if (property == null || !typeof(Brush).IsAssignableFrom(property.PropertyType))
        {
            if (DesignerProperties.GetIsInDesignMode(d))
            {
                if (property != null)
                {
                    throw new ArgumentException($"Could not blink for {d.GetType().Name}.{property.Name}", nameof(d));
                }
            }

            return;
        }

        AnimateBlink(e.NewValue as bool?, (UIElement)d, property);
    }

    private static DependencyProperty GetDefaultProperty(DependencyObject d)
    {
        if (d is Control)
        {
            return Control.BackgroundProperty;
        }

        if (d is Panel)
        {
            return Panel.BackgroundProperty;
        }

        if (d is Border)
        {
            return Border.BackgroundProperty;
        }

        if (d is Shape)
        {
            return Shape.FillProperty;
        }

        if (DesignerProperties.GetIsInDesignMode(d))
        {
            throw new ArgumentException($"Could not find property to blink for {d.GetType().Name}", nameof(d));
        }

        return null;
    }

    private static void AnimateBlink(bool? blink, UIElement element, DependencyProperty property)
    {
        if (element == null)
        {
            return;
        }
        if (blink == true)
        {
            var brush = element.GetValue(property);
            element.SetCurrentValue(OldBrushProperty, brush);
            element.SetValue(property, Brushes.Transparent);
            var from = element.GetFrom();
            var to = element.GetTo();
            var sb = new Storyboard();
            var duration = element.GetDuration();
            var animation = new ColorAnimation(from, to, duration)
            {
                AutoReverse = element.GetAutoReverse(),
                RepeatBehavior = element.GetRepeatBehavior()
            };
            Storyboard.SetTarget(animation, element);
            Storyboard.SetTargetProperty(animation, new PropertyPath($"{property.Name}.(SolidColorBrush.Color)"));
            sb.Children.Add(animation);
            sb.Begin();
        }
        else
        {
            var brush = element.GetValue(OldBrushProperty);
            element.BeginAnimation(property, null);
            element.SetCurrentValue(property, brush);
        }
    }
}

Использование:

<Grid>
    <Grid.Resources>
        <Style x:Key="BlinkWhenMouseOver"
               TargetType="{x:Type Border}">
            <Setter Property="local:Blink.When" Value="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" />
            <Setter Property="local:Blink.From" Value="Honeydew" />
            <Setter Property="local:Blink.To" Value="HotPink" />
            <Setter Property="BorderThickness" Value="5" />
            <Setter Property="local:Blink.Property" Value="{x:Static Border.BorderBrushProperty}" />
        </Style>
    </Grid.Resources>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Border Style="{StaticResource BlinkWhenMouseOver}" Background="Transparent"/>
    <Border Grid.Row="1"
            local:Blink.From="Aqua"
            local:Blink.To="Yellow"
            local:Blink.When="{Binding IsChecked,
                                       ElementName=ToggleBlink}" />
    <ToggleButton x:Name="ToggleBlink"
                  Grid.Row="2"
                  Content="Blink" />
</Grid>
1
Johan Larsson

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

 ColorAnimation animation;
    animation = new ColorAnimation();
    animation.AutoReverse =true;
0
MrvynB

В WPF использование анимации может быть лучше. Выражение blend имеет относительную анимацию/поведение.

0
Wendy369

Это хорошо сработало для меня.

У меня есть путь внутри кнопки (он рисует "X"):

<Path x:Name="MyDeleteRowButton" Stroke="Gray" Grid.Row="0" 
      Data="M1,5 L11,15 M1,15 L11,5" StrokeThickness="2" HorizontalAlignment="Center" 
      Stretch="None"/>

При наведении курсора мыши я хочу, чтобы крест стал красным, поэтому я добавляю:

<DataTemplate.Triggers>
    <!-- Highlight row on mouse over, and highlight the delete button. -->
    <EventTrigger RoutedEvent="ItemsControl.MouseEnter">
        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <!-- On mouse over, flicker the row to highlight it.-->
                    <DoubleAnimation
                        Storyboard.TargetProperty="Opacity"
                        From="0.5" 
                        To="1" 
                        Duration="0:0:0.250"  
                        FillBehavior="Stop"/>
                    <!-- Highlight the delete button with red. -->
                    <ColorAnimation
                        To="Red"
                        Storyboard.TargetName="MyDeleteRowButton"
                        Storyboard.TargetProperty="(Stroke).(SolidColorBrush.Color)"
                        Duration="0:0:0.100" 
                        FillBehavior="HoldEnd"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>
    </EventTrigger>

    <!-- Grey out the delete button. -->
    <EventTrigger RoutedEvent="ItemsControl.MouseLeave">
        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <!-- Space is precious: "delete" button appears only on a mouseover. -->
                    <ColorAnimation
                        To="Gray"
                        Storyboard.TargetName="MyDeleteRowButton"
                        Storyboard.TargetProperty="(Stroke).(SolidColorBrush.Color)"
                        Duration="0:0:0.100" 
                        FillBehavior="HoldEnd"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>
    </EventTrigger>

</DataTemplate.Triggers>

Самое запутанное в этом - это скобки внутри Storyboard.TargetProperty. Если вы удалите скобки, ничего не работает. 

Для получения дополнительной информации см. « propertyName Grammar » и « Storyboard.TargetProperty ».

0
Contango