Hello,
I am having fun with WPF and got a problem. I have googled and found this website that has the same problem of me but without any working solution.
The problem is that I have a button that do some processing of data (around 30 sec). I want to have the button to disable and to have log writing in a text box... the problem is that it doesn't disable and it doesn't wrote any thing on the textbox until the processing is completely done.
Any idea?
private void button1_Click(object sender, RoutedEventArgs e)
{
this.button1.IsEnabled = false;
//Long stuff here
txtLog.AppendText(Environment.NewLine + "Blabla");
//End long stuff here
this.button1.IsEnabled = true;
}
-
do it async. create a backgroundworker process to handle the data and the application will continue to respond. MSDN Resources on the Class. Since WPF is using C# (or VB.net) you can still use the same types of threading objects. I've used the background worker successfully in a WPF app myself.
Daok : Alright, like in normal C#. I thought it would have been something special with WPF:PDaok : And... the background working is not in the Toolbox hummmMasterMax1313 : just create an instance of the class directly, instead of the toolbox -
That operation is being performed on the UI thread. This means that it will block the Windows message pump from processing until it has completed. no pump = no UI updates. You should launch the job on another thread. I don't know WPF, but in C# I would use either the Thread or BackgroundWorker classes.
Daok : It doesn't work the same way, I am readying and you cannot use this.BeginInvoke... your answer is not complete sorry cannot accept.Ed Swangren : Well, the name is different, but the concept is the same. I said I did not know WPF. It's ok that you didn't accept, the accepted answer is far more complete. -
As others have said, use the
BackgroundWorkeror some other method of doing work asychronously.You can declare it under your
Window, initialize it somewhere like theLoadedevent, and use it in theClickevent. Here's your method, modified to useBackgroundWorker, assuming you've declared it under theWindowas_bw:private void Window_Loaded(object sender, RoutedEventArgs e) { _bw = new BackgroundWorker(); _bw.DoWork += new DoWorkEventHandler((o, args) => { //Long stuff here this.Dispatcher.Invoke((Action)(() => txtLog.AppendText(Environment.NewLine + "Blabla"))); }); _bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler((o, args) => { //End long stuff here this.Dispatcher.Invoke((Action)(() => this.button1.IsEnabled = true)); }); } private void button1_Click(object sender, RoutedEventArgs e) { this.button1.IsEnabled = false; _bw.RunWorkerAsync(); }Note that anything that modifies your UI from another thread must be done within a
Dispatcher.InvokeorDispatcher.BeginInvokecall, WPF does not allow you to get or setDependencyPropertyvalues from any thread but the one where the object was created (more about this here).If you wanted to read from
txtLoginstead of modifying it, the code would be the same://Long stuff here this.Dispatcher.Invoke((Action)(() => { string myLogText = txtLog.Text; myLogText = myLogText + Environment.NewLine + "Blabla"; txtLog.Text = myLogText; }));Daok : This is more what I have read yet on other website. Thx! Do you have a snippet to READ data... usually with 2.0 I do not need to do something but I have a cross thread exception while reading the textbox value :SRobert Macnee : Yes, getting or setting dependency properties must be done on the UI thread, so it has to be within a Dispatcher.Invoke call as above.Daok : Thank you, learn a lot from you today!Jacob Adams : +1 for the example
0 comments:
Post a Comment