我不知道如何在純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