Reputation: 2128
I'm trying to create a timer that returns to the main menu of my WPF application of, let's say, 30 seconds of inactivity. But I get the error "The calling thread cannot access this object because a different thread owns it." and it occurs in the FadeOut()
at storyboard.Begin(uc);
I've seen a few solutions involving invoking the dispatcher but I'm not to sure how to apply in my case?
public void ResetScreen()
{
if (!mainScreen)
{
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
myTimer.Interval = 1000;
myTimer.Start();
}
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
TransitionContent(oldScreen, newScreen);
}
private void FadeIn(FrameworkElement uc)
{
DoubleAnimation dAnimation = new DoubleAnimation();
dAnimation.Duration = new Duration(TimeSpan.FromSeconds(1.0));
dAnimation.From = 0;
dAnimation.To = 1;
Storyboard.SetTarget(dAnimation, uc);
Storyboard.SetTargetProperty(dAnimation, new PropertyPath(OpacityProperty));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(dAnimation);
storyboard.Begin(uc);
}
private void FadeOut(FrameworkElement uc)
{
DoubleAnimation dAnimation = new DoubleAnimation();
dAnimation.Duration = new Duration(TimeSpan.FromSeconds(1.0));
dAnimation.From = 1;
dAnimation.To = 0;
Storyboard.SetTarget(dAnimation, uc);
Storyboard.SetTargetProperty(dAnimation, new PropertyPath(OpacityProperty));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(dAnimation);
storyboard.Begin(uc);
}
private void TransitionContent(FrameworkElement oldScreen, FrameworkElement newScreen)
{
FadeOut(oldScreen);
FadeIn(newScreen);
}
Upvotes: 0
Views: 915
Reputation: 40788
Your problem is that the System.Timers.Timer event runs on a different thread than the UI thread. You can try directly invoking as others have mentioned or you could use DispatcherTimer.
Upvotes: 2
Reputation: 646
This one might be a solution:
this.Dispatcher.Invoke((Action)(()=>{
// In here, try to call the stuff which making some changes on the UI
});
Such as:
private void TransitionContent(FrameworkElement oldScreen, FrameworkElement newScreen)
{
this.Dispatcher.Invoke((Action)(()=>{
FadeOut(oldScreen);
FadeIn(newScreen);
});
}
Upvotes: 2