I have not used wpf alot and thought it would be a simple proccess to change the colour of an ellipse at runtime. I have a FileWatcher and in the event created I want to change the colour of the ellipse to a colour and back again, creating a blinking effect. (created is the ellipse, br4 is a solid colour brush defined in xaml)
public void watcherCreated(object seneder, FileSystemEventArgs e)
{
Application.Current.Resources["br4"] = new SolidColorBrush(Colors.Green);
created.Fill = (SolidColorBrush)Application.Current.Resources["br4"];
}
as soon as a file is created in the path which fires the event i get this error: Invalid operation exception
The calling thread cannot access this object because a different thread owns it.
I have looked for a solution with the freeze() method, but with no success.
created.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(
delegate()
{
Application.Current.Resources["br4"] = new SolidColorBrush(Colors.Green);
created.Fill = (SolidColorBrush)Application.Current.Resources["br4"];
}
));
got it thanks for comments
You can only access UI elements from the same thread in which they were created.
You should use Dispatcher.Invoke or Dispatcher.BeginInvoke to have a delegate called on the UI thread…where you can then access the “created” elements’ “Fill” property.
See this link for an explanation of the problem:
Instead of trying to set the changing colour in the UI…what you can do is expose a property on your ViewModel which holds a state.
When your FileWatcher notifies you of a newly created file (by calling your watcherCreated method) you just set that state in your ViewModel.
In your UI…use a Binding with a Converter to bind to the state property in your ViewModel. The converter will determine what Brush to use depending on the state e.g. if state is 1 return a Green brush, if state is 0 return a Red brush.
To reset the state back to the “off” position…you could have a timer that after say 1 second, etc…sets the state value back to off.
By doing this….you separate the state from the UI.
If in the future you wanted a more sophisticated way of showing the state in the UI…e.g. having an animation (using StoryBoards/Visual State Manager) that gradually fades away from Green back to Red…then you could have that animation triggered, once again based on the state in the ViewModel.