Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF - Cannot change a GUI property inside the OnChanged method (fired from FileSystemWatcher)

I want to change a GUI property in the OnChanged method... (in actuality im trying to set an image source.. but used a button here for simplicity). This is called everytime filesystemwatcher detects a change in a file.. and it gets to the "top" output.. but catches an exception when it tries to set the button width.

but if i put the same code in a button.. it works just fine. I sincerely don't understand why.. can someone help me?

private void OnChanged(object source, FileSystemEventArgs e)
        {
            //prevents a double firing, known bug for filesystemwatcher
            try
            {
                _jsonWatcher.EnableRaisingEvents = false;
                FileInfo objFileInfo = new FileInfo(e.FullPath);
                if (!objFileInfo.Exists) return;   // ignore the file open, wait for complete write

                //do stuff here                    
                Console.WriteLine("top");
                Test_Button.Width = 500;
                Console.WriteLine("bottom");
            }
            catch (Exception)
            {
                //do nothing
            }
            finally
            {
                _jsonWatcher.EnableRaisingEvents = true;
            }
        }

what i'm really trying to do instead of changing a button width:

BlueBan1_Image.Source = GUI.GetChampImageSource(JSONFile.Get("blue ban 1"), "avatar");
like image 916
user1189352 Avatar asked Mar 22 '23 07:03

user1189352


2 Answers

The problem is that this event is raised on a background thread. You need to marshal the call back to the UI thread:

// do stuff here                    
Console.WriteLine("top");
this.Dispatcher.BeginInvoke(new Action( () =>
{
    // This runs on the UI thread
    BlueBan1_Image.Source = GUI.GetChampImageSource(JSONFile.Get("blue ban 1"), "avatar");
    Test_Button.Width = 500;
}));
Console.WriteLine("bottom");
like image 193
Reed Copsey Avatar answered Apr 30 '23 16:04

Reed Copsey


I'm guessing that the FileSystemWatcher is calling your event handler on another thread. Inside your event handler, use your application's Dispatcher to marshal it back to the UI thread:

private void OnChanged(object source, FileSystemEventArgs e) {
    Application.Current.Dispatcher.BeginInvoke(new Action(() => DoSomethingOnUiThread()));
}

private void DoSomethingOnUiThread() {
    Test_Button.Width = 500;
}
like image 39
Steve Avatar answered Apr 30 '23 17:04

Steve