You could simply use a flag: set a flag on your VM called 'RecentlyChangedFlag'. Pulse it to true then false whenever the appropriate value(s) change. You could do that like this.
Up vote 1 down vote favorite share g+ share fb share tw.
I seem to have reached some sort of MVVM breaking point here. I would like for a control to have its opacity animated for half a second (DoubleAnimation from 0.5 to 1.0) when the underlying view model object have its "Status" property changed. I achieved this at first using a DataTrigger but since I haven't found a way to react to ANY change, just a given value, I had to always flip the VM objects "Status" property to a special "pending" value before setting it to its intended value.
(Is there a way to react to ANY change btw? ) This was hacky so I started fiddling with EventTriggers instead... This is what I've tried so far: Using a normal EventTrigger This seems to require a RoutedEvent but that, in turn, requires that my underlying view model object inherits from DependencyObject. Using i:Interaction.
Triggers That way I can listen to and react to normal . NET events but I haven't found a way to start a StoryBoard using that approach. Using i:Interaction.
Triggers and writing a Behavior This experiment fell short on the fact I found no way to attach my custom behavior to its associated control. This is what the XAML looked like: And here's the custom behavior: class OpacityBehavior : Behavior { 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); } } That didn't work because the XAML parser required it to be attached directly to "MyControl" but I need to attach it to the event trigger. I then tried this approach: class OpacityBehavior : Behavior { 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)); } } This failed on the fact that lookupVisualParent doesn't work. The logical parent of the behavior is always null. It strikes me this should be a fairly common task?
Is there a good solution to this problem? I find it strange that I will have write my view model classes so that they derive from DependencyObject in order to start an animation when an event fires. Cheers wpf events animation eventtrigger link|improve this question asked Oct 19 '11 at 16:59Jonas Rembratt1237 47% accept rate.
You could simply use a flag: set a flag on your VM called 'RecentlyChangedFlag'. Pulse it to true, then false, whenever the appropriate value(s) change. You could do that like this: private bool _changedFlag; public bool ChangedFlag { get { if (_changedFlag) { _changedFlag = false; OnPropertyChanged("ChangedFlag"); return true; } // (else...) return false; } protected set { _changedFlag = value; OnPropertyChanged("ChangedFlag"); } } I.e.
, with the above code set ChangedFlag = true when you want to signal the animation to start. It will be reset to false after WPF queries the true value. Then have the animation occur when the value of RecentlyChangedFlag is true, as an EnterAction for instance.
Hope that helps.
Thanks but that's how I originally "solved" it (using a DataTrigger) but, as I pointed out in the OP, that's hacky. I'm fairly new to WPF so it might be this is actually the normal way of triggering behaviors/animations from the VM but to me this appear to be working around a limitation that shouldn't be there. Could it be that you simply cannot trigger animations from events in the VM?
– Jonas Rembratt Oct 20 '11 at 6:43 A ViewModel exists to translate a model into something a view can use. As such it's the perfect place to do things like this. It's not that hacky IMO and a flag indicating that something important has changed should exist in the VM.
So long as the ViewModel stands up on its own, it's not an issue. A ViewModel having a flag to indicate whatever 'event' your talking about - if you call it the right thing, it doesn't seem too out of place? – Kieren Johnstone Oct 20 '11 at 7:39 I'm not going to be religious about this but it does seem strange that its impossible to trigger animations from events.
After all, events are there to signal state changes. Having to add a second property just to signal state changes to the first is a workaround IMHO. I'm surprised to see that the tools made available by WPF is that deficient.
I can certainly live with the "state property solution" in this particular case but I envision my VM classes will be full of such properties in the future. There has to be a better way, right? – Jonas Rembratt Oct 20 '11 at 13:55.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.