Search code examples
c#.netwpfmultithreadingdispatcher

Updating a 2nd window control from events in an object created in the 1st window


here's what I need (it's a bit hard to explain):

I have 2 window controls: MainWindow and FileMover and 1 util class: FileMonitor

MainWindow created a new object of FileMonitor for testing purposes on it's Loaded event, which creates a FileSystemWatcher and a Timer object. The FileSystemWatcher watches a given folder for Created and Changed events, and the Timer is added as some kind of event buffer (when eg copying a folder or large file to the folder being watched, this generates several events. I only want to act on the first event, not the rest). This means, that not until the timer stops and generates its Elapsed event is the FileMover window created. This window has some basic file/folder copy/move logic and a ProgressBar control to show the current status.

My problem is this: The ProgressBar control does not update during the file processing. Only when the copy/move method returns, the progress bar is updated. I've tried using both FileMover's dispatcher and the ProgressBar dispatcher, but none of those work.

I'f the above is very unclear, let me know! Here's my source:

Source: http://pastie.org/1139570

(Had to put both source files in 1 paste because of site limitations..)


Solution

  • You must load the file in another thread. If not, the UI will not be refreshed. A simple way to do this is the BackgroundWorker-class. Here a short example:

    BackgroundWorker bgWorker = new BackgroundWorker() { WorkerReportsProgress=true};
    bgWorker.DoWork += (s, e) => {
        // Load here your file/s
        // Use bgWorker.ReportProgress(); to report the current progress
    };
    bgWorker.ProgressChanged+=(s,e)=>{
        // Here you will be informed about progress 
        //  (if bgWorker.ReportProgress() was called in DoWork)
    };
    bgWorker.RunWorkerCompleted += (s, e) => {
        // Here you will be informed if the job is done
    };
    bgWorker.RunWorkerAsync();