嘗試在展開和摺疊事件期間使用行爲對擴展器進行動畫製作,它在展開時起作用,但在摺疊時不起作用。花費了相當長的一段時間試圖找出原因(可見性==摺疊)後,我無法在摺疊時使它變成動畫。使用行爲動畫擴展器
在抓取初始內容大小方面存在一些破綻,動畫在內容更改的情況下肯定會不正確,但不會有類ContentChanged掛鉤的事件,並且在內容更改時抓取新大小。
行爲:
public class AnimatedExpanderBehavior : Behavior<Expander>
{
public Duration Duration { get; set; }
private Size ContentSize { get; set; }
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Collapsed += AssociatedObject_Collapsed;
AssociatedObject.Expanded += AssociatedObject_Expanded;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Collapsed -= AssociatedObject_Collapsed;
AssociatedObject.Expanded -= AssociatedObject_Expanded;
}
private void AssociatedObject_Collapsed(object sender, RoutedEventArgs e)
{
var expander = sender as Expander;
if (expander != null)
{
var name = expander.Content as FrameworkElement;
if (name != null)
{
// Does not happen, collapses instantly instead
var animation = new DoubleAnimation(name.ActualHeight, 0, Duration);
name.BeginAnimation(FrameworkElement.HeightProperty, animation);
}
}
}
private void AssociatedObject_Expanded(object sender, RoutedEventArgs e)
{
var expander = sender as Expander;
if (expander != null)
{
var name = expander.Content as UIElement;
if (name != null)
{
// Grabbing initial content size
if (ContentSize.Width <= 0 && ContentSize.Height <= 0)
{
name.Measure(new Size(9999, 9999));
ContentSize = name.DesiredSize;
}
var animation = new DoubleAnimation(0, ContentSize.Height, Duration);
name.BeginAnimation(FrameworkElement.HeightProperty, animation);
}
}
}
}
用法:
<Expander>
<i:Interaction.Behaviors>
<behaviors:AnimatedExpanderBehavior Duration="0:0:0.2" />
</i:Interaction.Behaviors>
<Rectangle Height="100" Fill="Red" />
</Expander>
有趣的是我一直期待的Windows用戶界面是怎麼做的,我是絕對肯定的是,它是做左右逢源,而事實上它只有在擴展時纔會這樣做。
是否有任何形式的限制,會阻止實現這種動畫時崩潰?
編輯
新的代碼,但它不當而原來的擴張做內容的變化調整:
private void AssociatedObject_Expanded(object sender, RoutedEventArgs e)
{
var expander = sender as Expander;
if (expander != null)
{
var name = expander.Content as FrameworkElement;
if (name != null)
{
_expandSite.Visibility = Visibility.Visible;
double height;
if (_firstExpansion)
{
name.Measure(new Size(9999, 9999));
height = name.DesiredSize.Height;
_firstExpansion = false;
}
else
{
height = name.RenderSize.Height;
}
var animation = new DoubleAnimation(0, height, new Duration(TimeSpan.FromSeconds(0.5d)));
name.BeginAnimation(FrameworkElement.HeightProperty, animation);
}
}
}
除了在第一次擴張沒有它的偉大工程發生的,我管理,使用該決定使用哪個高度從RenderSize或DesiredSize但還有一個布爾值,擴展時不其內容的變化,除非它的擴展或收縮而調整本身原始風格確實。我想現在我會忘記它,因爲如果沒有影響原始行爲的副作用,我就無法工作。但任何想法都歡迎! – Aybe
@Aybe因爲也許這動畫握住height屬性時,它被動畫,並將其鎖定,由於動畫優先。雙方的展開/摺疊動畫從已完成的事件設置「名稱」元素的高度,它的ActualHeight然後開始與第二個參數爲null,有效去除動畫優先級相同的一個新的高度動畫。這應該讓動畫不會阻止未來的調整。 – Viv
@Aybe我已經更新了我的答案有一個下載鏈接,應該有一個大小調整問題的修補程序,以及一個樣本。我不需要像第一次展開時提到的動畫那樣的任何布爾值。嘗試下載並查看它對你的行爲是否有所不同。在示例中,您有兩個按鈕來修改可用於測試大小更改的'Expander.Content'大小。 – Viv