我似乎已經在這裏達到了某種MVVM的突破點。使用MVVM從事件觸發動畫
當底層視圖模型對象的「狀態」屬性發生更改時,我想讓控件的不透明度動畫半秒(DoubleAnimation從0.5到1.0)。我首先使用DataTrigger實現了這一點,但由於我沒有找到一種方法來對任何更改做出反應,只是給定的值,我必須在設置它之前始終將VM對象「Status」屬性翻轉爲特殊的「pending」值達到預期的價值。 (?有沒有辦法BTW應對任何變化)
這是哈克,所以我開始EventTriggers而不是擺弄......
這是我到目前爲止已經試過:
- 使用正常的
EventTrigger
這似乎需要一個RoutedEvent,但這反過來要求我的基礎視圖模型對象從DependencyObject繼承。
- 使用
i:Interaction.Triggers
這樣我可以聽和作出反應的正常.NET事件,但我還沒有找到一種方法,使用這種方法來啓動一個StoryBoard
。
- 使用
i:Interaction.Triggers
續寫Behavior
這個實驗不及上,我發現沒有辦法我的自定義行爲附加到其相關的控制的事實。
這就是XAML看起來像:
<cc:MyControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Updated">
<i:Interaction.Behaviors>
<cv:OpacityBehavior Duration="0:0:0:5" />
</i:Interaction.Behaviors>
</i:EventTrigger>
</i:Interaction.Triggers>
而這裏的自定義行爲:
class OpacityBehavior : Behavior<MyControl>
{
public Duration Duration { get; set; }
protected override void OnAttached()
{
base.OnAttached();
var animation = new DoubleAnimation(0.5, 1, Duration, FillBehavior.HoldEnd);
var associatedObject = lookupVisualParent(this);
associatedObject.BeginAnimation(UIElement.OpacityProperty, animation);
}
}
因爲XAML解析器需要它那沒有工作直接連接到顯示「myControl 「但我需要將其附加到事件觸發器。然後,我嘗試這個辦法:
class OpacityBehavior : Behavior<DependencyObject>
{
public Duration Duration { get; set; }
protected override void OnAttached()
{
base.OnAttached();
var animation = new DoubleAnimation(0.5, 1, Duration, FillBehavior.HoldEnd);
var associatedObject = lookupVisualParent(this);
associatedObject.BeginAnimation(UIElement.OpacityProperty, animation);
}
private UIElement lookupVisualParent(DependencyObject dObj)
{
if (dObj is UIElement)
return (UIElement) dObj;
if (dObj == null)
return null;
return lookupVisualParent(LogicalTreeHelper.GetParent(dObj));
}
}
這個失敗的事實,lookupVisualParent
不起作用。該行爲的邏輯父項始終爲null
。
這讓我覺得這應該是一個相當普遍的任務?有沒有解決這個問題的好方法?我發現奇怪的是,我將編寫我的視圖模型類,以便它們從DependencyObject
派生,以便在事件觸發時啓動動畫。
乾杯
謝謝,但這就是我最初「解決」它(使用DataTrigger),但正如我在OP中指出的那樣,這很不好。我對WPF相當陌生,所以它可能是觸發虛擬機的行爲/動畫的正常方式,但對我來說,這似乎正在解決一個不應該存在的限制。難道你不能在虛擬機中觸發事件的動畫? –
ViewModel存在將模型轉換爲視圖可以使用的內容。因此,它是完成這種事情的最佳地點。這不是那種駭人的海事組織和一個標誌,表明重要的變化應該存在於虛擬機中。只要ViewModel獨立存在,這不是問題。一個ViewModel有一個標誌來表示你所說的任何'事件' - 如果你把它稱爲正確的東西,它看起來不太合適? –
我對此不會很虔誠,但看起來很奇怪,它不可能從事件中觸發動畫。畢竟,事件在那裏表示狀態的變化。不得不添加第二個屬性來向第一個狀態發送狀態更改是一種解決方法。我很驚訝地發現WPF提供的工具缺乏。在這種特殊情況下,我當然可以與「國有資產解決方案」一起生活,但我預計未來我的虛擬機課程將充滿此類特性。必須有更好的方法,對吧? –