0

I have a simple WPF button and a textbox in my WPF application(not using MVC or binding at all). I like to be able to do the following upon clicking the button:

1) Clear the textbox

2) Create the result

3) assign the result to the textbox

I used Textbox.Clear, TextBox.Text= String.Empty, delegates and a dispatcher approach like

private void button_Click(object sender, RoutedEventArgs e)
    {
        Application.Current.Dispatcher.BeginInvoke(new Action (ClearReportTxtBox), DispatcherPriority.Send);
        System.Threading.Thread.Sleep(5000);
        runTest();
    }


private void ClearReportTxtBox()
    {
        Report_textBox.Text = string.Empty;
    }

None of them working correctly for me. The dispatcher method is somehow working but not as I wish. It seems that the Clear task will be queued and when the all actions in the button click handler are finished, it will come into play and delete the textbox, but this causes that the generated report and already assigned to the textbox (created by runtest in the code above) will be deleted as well. Hence it is too late delete action and eliminate the whole result.

Currently it seems to me that by clicking on the button the UIthread blocks and takes the control. The Dispatcher will queue the delete action as next action after finishing the button click.

Is it possible to force delete at the beginning and then do the rest? What I like to reach is that I pause the button activity and do delete at first action and then continue with the rest of actions in the button handler.

Am I doing something wrong?

Thank you for your help in advance.

user2585405
  • 83
  • 2
  • 12
  • What's the point of the async operation? Can't you just clear the textbox in the button handler? – jamesSampica Aug 23 '13 at 20:07
  • The point of confusion here for me is "Create the result". Where in your code are you doing that, what exactly is that step doing? If you're assigning something else to the textbox then just do that instead of clearing it and then setting it to something else. You can disable the textbox in the interim if its some sort of intensive process. If you absolutely need to run something async, can you use TPL tasks instead? – Chris Klepeis Aug 23 '13 at 20:39
  • The dispatcher is the thread you are already running on with the button click. What is the point of all this. Just clear the text box and all the other stuff on the click event – Mark Homer Aug 24 '13 at 22:32
  • I like to reset(cleanup) the textbox at the beginning. The issue is, if there is some kind of result in the textbox, by (re)clicking the button, it doesn't reset the textbox immediately and still shows the old result till the whole activities in the button are done. – user2585405 Aug 26 '13 at 12:32

1 Answers1

0

The "Dispatcher.BeginInvoke" is kinda weird for what you want to do

All the UI update has to be done on main thread. Since the "Button_click" event is executing on main thread, the delegate you push into Dispatcher can only be executed AFTER the button_click handle is completed. That's why the execution sequence becomes 1. The GUI freeze because Thread.Sleep 2. RunTest 3. ClearReportTextBox

Guess you can try sth like the following instead.

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {            
        ClearReportTxtBox();

        Task.Factory.StartNew(RunTest);
    }

    private void ClearReportTxtBox()
    {
        MyTextBox.Text = string.Empty;
    }

    private void RunTest()
    {
        System.Threading.Thread.Sleep(5000);

        if (dispatcher != null && !dispatcher.CheckAccess())
        {
            dispatcher.Invoke(priority, ()=> MyTextBox.Text = "123");
        }
        else
        {
            MyTextBox.Text = "123";
        }                
    }
cscmh99
  • 2,701
  • 2
  • 15
  • 18
  • Thank you for your response but got an exception by implementing your recommendation. The new thread can't access to the textbox because it seems to belong to the other thread. – user2585405 Aug 26 '13 at 13:15