(這是用不同的方式來解決my earlier problem的嘗試。)結合WPF DataTriggers和故事板代碼
我創建它使用我希望能夠通過設置動畫放射漸變畫筆的用戶控件在我的視圖模型上的一個屬性。漸變畫筆也有一些綁定到視圖模型的屬性。
的XAML用戶控件是(一些性質剪斷爲了簡潔):
<UserControl x:Class="WpfApplication1.AnimatedLineArrow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Controls="clr-namespace:Microsoft.Expression.Controls;assembly=Microsoft.Expression.Drawing"
mc:Ignorable="d" d:DesignHeight="150" d:DesignWidth="300"
Name="animatedLineArrow">
<Grid>
<Controls:LineArrow x:Name="ArrowControl"
StartCorner="{Binding ElementName=animatedLineArrow, Path=StartCorner, FallbackValue=TopRight}"
Width="{Binding ElementName=animatedLineArrow, Path=Width, FallbackValue=200}"
Height="{Binding ElementName=animatedLineArrow, Path=Height, FallbackValue=200}"
<Controls:LineArrow.Stroke>
<RadialGradientBrush RadiusX="0.2" RadiusY="1.0"
Center="{Binding ElementName=animatedLineArrow, Path=StartPoint, Mode=OneWay}"
GradientOrigin="{Binding ElementName=animatedLineArrow, Path=StartPoint, Mode=OneWay}">
<RadialGradientBrush.GradientStops>
<GradientStop Color="{Binding ElementName=animatedLineArrow, Path=HighlightColour, Mode=OneWay, FallbackValue=Cyan}" Offset="0.0" />
<GradientStop Color="{Binding ElementName=animatedLineArrow, Path=PrimaryColour, Mode=OneWay, FallbackValue=Navy}" Offset="1.0" />
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</Controls:LineArrow.Stroke>
</Controls:LineArrow>
</Grid>
</UserControl>
代碼隱藏設置的各種依賴屬性,以及該控件的Loaded事件,定義了一個故事板進行動畫顯示放射漸變的中心和漸變原點屬性,然後確定應該對那些依賴屬性之一的值響應DataTriggers:
private void ConfigureAnimation(object sender, EventArgs e)
{
StartPoint = StartingPoints[StartCorner];
EndPoint = EndingPoints[StartCorner];
AnimatedLineArrow arrow = (AnimatedLineArrow)sender;
Storyboard storyboard = CreateStoryboard(arrow);
DataTrigger startTrigger = new DataTrigger
{
Binding = new Binding
{
Path = new PropertyPath(IsRunningProperty),
RelativeSource = RelativeSource.Self
},
Value = true
};
startTrigger.EnterActions.Add(new BeginStoryboard { Storyboard = storyboard, Name = "beginStoryboard" });
DataTrigger endTrigger = new DataTrigger
{
Binding = new Binding
{
Path = new PropertyPath(IsRunningProperty),
RelativeSource = RelativeSource.Self
},
Value = false
};
endTrigger.EnterActions.Add(new StopStoryboard { BeginStoryboardName = "beginStoryboard" });
Style style = new Style(typeof(AnimatedLineArrow));
style.Triggers.Add(startTrigger);
style.Triggers.Add(endTrigger);
arrow.Style = style;
}
private Storyboard CreateStoryboard(AnimatedLineArrow arrow)
{
Storyboard storyboard = new Storyboard();
PointAnimation originAnimation = new PointAnimation(StartingPoints[StartCorner], EndingPoints[StartCorner], Duration, FillBehavior.HoldEnd);
PointAnimation centreAnimation = originAnimation.Clone();
Storyboard.SetTarget(originAnimation, arrow);
Storyboard.SetTargetProperty(originAnimation, new PropertyPath(RadialGradientBrush.GradientOriginProperty));
Storyboard.SetTarget(centreAnimation, arrow);
Storyboard.SetTargetProperty(centreAnimation, new PropertyPath(RadialGradientBrush.CenterProperty));
storyboard.Children.Add(originAnimation);
storyboard.Children.Add(centreAnimation);
return storyboard;
}
當我嘗試運行該項目,它成功地編譯和窗口加載SUCC在默認狀態下,控件處於有效狀態。然而,當DataTrigger大火的第一次,我得到以下異常:
System.InvalidOperationException was unhandled
Message='beginStoryboard' name cannot be found in the name scope of 'System.Windows.Style'.
Source=PresentationFramework
我已經附上示例項目to demonstrate what I am trying to achieve。
非常感謝您的提示,@CodeNaked。它肯定會照顧DataTrigger開啓時產生的IOE。然而,動畫仍然沒有發生 - 關於爲什麼會這樣的想法? – 2011-05-03 23:11:38
我已經嘗試了所有的數據觸發器事件,並且在完成設置時啓動故事板,但仍然沒有動畫。這表明問題在於我如何設置故事板及其動畫。 – 2011-05-04 06:36:27
@大衛 - 我更新了我的答案。 – CodeNaked 2011-05-04 11:27:21