我不知道如何在纯XAML一举两得动画(淡入和淡出)。但简单的淡出可以实现得比较简单。用触发器替换DataTriggers,并删除ExitActions,因为它们在淡出方案中没有意义。这是你将有:
<Style TargetType="FrameworkElement" x:Key="animatedList">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0.0" To="1.0" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
但是,嘿,不要放弃。如果你想支持这两个动画,我可以在XAML后面提供小编码。我们做了一招后,我们会得到你想要的东西通过添加一行代码在XAML:
<Button Content="Fading button"
x:Name="btn"
loc:VisibilityAnimation.IsActive="True"/>
每次我们改变btn.Visibility从可见光到隐藏/折叠按钮时会淡出。每次我们改变Visibility时,按钮都会淡入。这个技巧可以用于任何FrameworkElement(包括ListView :))。
这里是VisibilityAnimation.IsActive附加属性的代码:
public class VisibilityAnimation : DependencyObject
{
private const int DURATION_MS = 200;
private static readonly Hashtable _hookedElements = new Hashtable();
public static readonly DependencyProperty IsActiveProperty =
DependencyProperty.RegisterAttached("IsActive",
typeof(bool),
typeof(VisibilityAnimation),
new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsActivePropertyChanged)));
public static bool GetIsActive(UIElement element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool)element.GetValue(IsActiveProperty);
}
public static void SetIsActive(UIElement element, bool value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(IsActiveProperty, value);
}
static VisibilityAnimation()
{
UIElement.VisibilityProperty.AddOwner(typeof(FrameworkElement),
new FrameworkPropertyMetadata(Visibility.Visible, new PropertyChangedCallback(VisibilityChanged), CoerceVisibility));
}
private static void VisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// So what? Ignore.
}
private static void OnIsActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var fe = d as FrameworkElement;
if (fe == null)
{
return;
}
if (GetIsActive(fe))
{
HookVisibilityChanges(fe);
}
else
{
UnHookVisibilityChanges(fe);
}
}
private static void UnHookVisibilityChanges(FrameworkElement fe)
{
if (_hookedElements.Contains(fe))
{
_hookedElements.Remove(fe);
}
}
private static void HookVisibilityChanges(FrameworkElement fe)
{
_hookedElements.Add(fe, false);
}
private static object CoerceVisibility(DependencyObject d, object baseValue)
{
var fe = d as FrameworkElement;
if (fe == null)
{
return baseValue;
}
if (CheckAndUpdateAnimationStartedFlag(fe))
{
return baseValue;
}
// If we get here, it means we have to start fade in or fade out
// animation. In any case return value of this method will be
// Visibility.Visible.
var visibility = (Visibility)baseValue;
var da = new DoubleAnimation
{
Duration = new Duration(TimeSpan.FromMilliseconds(DURATION_MS))
};
da.Completed += (o, e) =>
{
// This will trigger value coercion again
// but CheckAndUpdateAnimationStartedFlag() function will reture true
// this time, and animation will not be triggered.
fe.Visibility = visibility;
// NB: Small problem here. This may and probably will brake
// binding to visibility property.
};
if (visibility == Visibility.Collapsed || visibility == Visibility.Hidden)
{
da.From = 1.0;
da.To = 0.0;
}
else
{
da.From = 0.0;
da.To = 1.0;
}
fe.BeginAnimation(UIElement.OpacityProperty, da);
return Visibility.Visible;
}
private static bool CheckAndUpdateAnimationStartedFlag(FrameworkElement fe)
{
var hookedElement = _hookedElements.Contains(fe);
if (!hookedElement)
{
return true; // don't need to animate unhooked elements.
}
var animationStarted = (bool) _hookedElements[fe];
_hookedElements[fe] = !animationStarted;
return animationStarted;
}
}
这里最重要的是CoerceVisibility()方法。正如你所看到的,我们不允许改变这个属性,直到淡入淡出的动画完成。
此代码既不是线程安全的也没有缺陷。它唯一的意图是显示方向:)。所以请随时改进,编辑并获得声望;)。
可以通过以下方式实现淡入和淡出重复效果:a)将DoubleAnimation上的AutoReverse属性设置为True,b)将R epeatBehaviour物业在故事板永远 – 2010-06-17 02:36:08
你注意到*// /注:小问题在这里。这可能会或可能会制动 //绑定到知名度属性。* ...有谁知道如何解决这个问题?我真的希望能够将可见性绑定到模型值。 – Akku 2012-01-10 15:59:24