私は正しい決断を下すのに助けが必要です。何らかのイベントが発生したときに、ユーザーコントロールの背景色をアニメーション化する必要があります。その場合、背景を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);
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>
背景が凍結されたインスタンスである場合、System.InvalidOperationExceptionを受け取る可能性があります。
オブジェクトがシールまたはフリーズされているため、「System.Windows.Media.SolidColorBrush」の「Color」プロパティをアニメーション化できません。
このメッセージを修正するには、コントロールの背景を非凍結インスタンスに割り当てます。
// Do not use a frozen instance
this.elGrid.Background = new SolidColorBrush(Colors.Orange);
this.elGrid.Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);
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でバインドする必要はありません。 //楽しんで!
以下は、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秒後に元の色に戻す場合は、
ColorAnimation animation;
animation = new ColorAnimation();
animation.AutoReverse =true;
WPFでは、アニメーションを使用する方が良いかもしれません。エクスプレッションブレンドには、相対的なアニメーション/動作があります。
これは私にとってはうまくいきました。
ボタン内にパスがあります(「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 」を参照してください。