2

I have a button called "Verify". When clicked it should change its content to "Verifying..." and once processing is completed it should show "Verified". How should we achieve this? I am new to wpf. Any help will be appreciated.

private void btnVerify_Click(object sender, RoutedEventArgs e)  
{  
    btnVerify.Content = new BitmapImage(new Uri("Verifying.png", UriKind.Relative));
    VerifyData(); // this takes almost few seconds to few minutes 
    btnVerify.Content = new BitmapImage(new Uri("Verified.png", UriKind.Relative)); 
}
PVitt
  • 11,500
  • 5
  • 51
  • 85
user1222006
  • 159
  • 1
  • 3
  • 11
  • 1
    Have you tried anything at all and if so can you provide code as to where you are stuck? – Alex Mendez Feb 20 '12 at 21:03
  • private void btnVerify_Click(object sender, RoutedEventArgs e) { btnVerify.Content = new BitmapImage(new Uri("Verifying.png", UriKind.Relative)); VerifyData(); // this takes almost few seconds to few minutes btnVerify.Content = new BitmapImage(new Uri("Verified.png", UriKind.Relative)); } – user1222006 Feb 20 '12 at 21:24
  • 1
    @user1222006 - Please post that code in your question itself next time and use the code markup (four spaces at the beginning of each line) so that it is easy to read and understand. Thanks. – IAmTimCorey Feb 20 '12 at 21:40
  • is all of `VerifyData()` code executing on the UI thread? – Jake Berger Feb 20 '12 at 21:50

2 Answers2

0

There isn't much to work with here, but I think I can answer your question. As I see it, there are a couple simple ways to do this.

First, you could simply change the button's text to "Verify" again at the end of whatever process it kicks off. For example:

OnClick()
{
   Button.Text = "Verifying...";
   DoSomething();
}

DoSomething()
{
   ...
   Button.Text = "Verify";
}

The problem with this approach is that it is quick and dirty. It assumes you are modifying your View (User Interface) directly through code. It also assumes that your DoSomething method can also manipulate your View. Not a best practice but it is simple.

Another way would be to fire an event when the process was done. Your form (or ViewModel) could listen for the event to fire and then change the text value of the button back to "Verify". This is a bit more best practice in nature, especially if you are using something like MVVM and you do this work in your ViewModel. Since you can get your button's text from your ViewModel, you can change it initially and finally from there.

Edit From the updated information you have posted, it looks like you might have an issue with the screen refreshing. This is most likely because you are doing a synchronous process that is locking the update until after the whole process has completed. One way (hack) to get around this would be to follow the directions listed here:

http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx

I would much rather see you refactor this code to be more thread-friendly, however. If the process is taking long enough that you need to see a wait indicator on the screen (like "Validating..."), I would recommend using a background worker or some other sort of asynchronous process to handle the actual work so that your UI does not lock up. That, however, is a more advanced topic that might be beyond the scope of what you want to learn as a beginner. If so, I would suggest either doing the above hack for now or just living with the issue.

IAmTimCorey
  • 16,412
  • 5
  • 39
  • 75
  • Thank you Biggs, but somehow it is updating the button text when the entire process on click of event is completed. Am I missing anything? – user1222006 Feb 20 '12 at 21:12
  • Can you post some code in your question that will show us what you are doing? It sounds like maybe you are doing all of the right steps but maybe the screen doesn't refresh to say "verifying..." before the process completes and it is changed back. That would be a result of doing a synchronous process. Fixing something like that would be a bit more complicated. – IAmTimCorey Feb 20 '12 at 21:39
  • You need to tell the application to process the text change before continuing with the code. For example, you can call something like: System.Windows.Forms.Application.DoEvents – Alex Mendez Feb 20 '12 at 21:42
  • @AlexMendez - I don't believe that will work in WPF though. He will need to do something more complicated like so: http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx – IAmTimCorey Feb 20 '12 at 22:25
  • @BiggsTRC - System.Windows.Forms.Application.DoEvents is mentioned in the following: http://stackoverflow.com/questions/2667370/how-do-i-doevents-in-wpf. This is where I got the information. Have not personally tested it. – Alex Mendez Feb 20 '12 at 23:33
  • @AlexMendez - I see, but unfortunately that is incorrect information. If you read the accepted answer, you will see the following phrase: "There should be no benefit to calling DoEvents". There are "DoEvents"-like commands that you can run but really it is still a work-around for the fact that you are doing blocking operations on the UI thread. DoEvents was for Windows Forms (which isn't the same thing as WPF) and it was a work-around for an issue that proper threading fixes. Now that threading is more mature, WPF doesn't need such a command and so it was (intentionally) left out. – IAmTimCorey Feb 21 '12 at 16:53
0

because you're new to WPF, i'm assuming you're NOT using MVVM. in that case:

hook onto the Click event and in the method:

OnVerifyClick(object sender, RoutedEventArgs e)
{
    Button verifyButton = sender as Button;
    if(verifyButton == null) { return; }

    verifyButton.Content = "Verifying...";
    DoProcessing();
    verifyButton.Content = "Verified";    
}
Jake Berger
  • 5,237
  • 1
  • 28
  • 22
  • you are correct, I am not sure about MVVM and will go through it. BTW, I was trying the below code and it always displays verified. private void btnVerify_Click(object sender, RoutedEventArgs e) { btnVerify.Content = new BitmapImage(new Uri("Verifying.png", UriKind.Relative)); VerifyData(); btnVerify.Content = new BitmapImage(new Uri("Verified.png", UriKind.Relative)); } – user1222006 Feb 20 '12 at 21:30
  • it may be because the `VerifyData()` code executes so quickly... put a `System.Threading.Thread.Sleep(3000);` immediately after `VerifyData()` to see if that's the issue. – Jake Berger Apr 04 '12 at 13:42