locked
problem with Progressbar RRS feed

  • Question

  • private void button_Click(object sender, RoutedEventArgs e)
    {
    int i;
    for ( i = 0; i <
    100000 ; i++)
    {
    progressBar1.Value=i/1000;
    }
    progressBar1.Visibility = Visibility.Collapsed;
    }

    Why i can't see the intermidiate values of progressBar1?
    Can anybody show code, which can show intermidiate values of circle in progressBar?
    Tuesday, May 17, 2011 7:43 PM

Answers

  • You're doing all of that in a click handler. The code runs in the UI thread and the screen won't dynamically update in real time while you set the progress bar value. The screen won't update until the click handler exits (at that point, your progress bar will be at value 100 and collapsed).

    You can set up a DispatcherTimer, and at each Tick event advance the progress bar to the next value.
    Tuesday, May 17, 2011 10:18 PM
  • Your UI thread is doing the work inside the button click procedure.  Since it is busy running the loop code, it can't update your UI.

    Move the work into another method, and call it on a worker thread.  Then use Dispatcher.Begin invoke and a lambda to marshal the update back to the UI thread.

     
        private void button1_Click(object sender, RoutedEventArgs e)  
        {  
          ThreadPool.QueueUserWorkItem(OtherWork);  
     
        }  
     
        private void OtherWork(object o)  
        {  
          for (int i = 0; i < 100; i++)  
          {  
             
     
            Thread.Sleep(10);  
            Dispatcher.BeginInvoke(() => progressBar1.Value = i);  
          }  
     
          Dispatcher.BeginInvoke(() => progressBar1.Visibility = Visibility.Collapsed);  
        } 
    Tuesday, May 17, 2011 11:08 PM
  • Anything involving the UI needs to be inside the BeginInvoke
    Thursday, May 19, 2011 6:52 PM
  • The Textbox is also a UI element.  You cannot update any UI element from a non UI thread.
    Thursday, May 19, 2011 7:01 PM
  • But i only need to take text from textbox. I don`t update it.

    Anything that accesses a UI element(your textbox in this case) must be done on the UI thread. Whether its get or set or whatever.
    Thursday, May 19, 2011 7:24 PM
  • Moving the call to the textbox.Text property inside your lambda expression should work. Like this:

            private void button1_Click(object sender, RoutedEventArgs e)  
            {  
                ThreadPool.QueueUserWorkItem(OtherWork);  
            }  
     
            private void OtherWork(object o)   
            {   
                string a;   
                for (int i = 0; i <100; i++)   
                {   
       
                    Thread.Sleep(10);   
                    Dispatcher.BeginInvoke(() =>   
                    {  
                        a = textbox.Text;  
                        progressBar1.Value = i;  
                         
                    });  
     
                      
                }  
     
                Dispatcher.BeginInvoke(() => progressBar1.Visibility = Visibility.Collapsed);   
            } 
    Saturday, May 21, 2011 12:26 PM

All replies

  • I think I see the problem....
    Tuesday, May 17, 2011 7:54 PM
  • You're doing all of that in a click handler. The code runs in the UI thread and the screen won't dynamically update in real time while you set the progress bar value. The screen won't update until the click handler exits (at that point, your progress bar will be at value 100 and collapsed).

    You can set up a DispatcherTimer, and at each Tick event advance the progress bar to the next value.
    Tuesday, May 17, 2011 10:18 PM
  • Your UI thread is doing the work inside the button click procedure.  Since it is busy running the loop code, it can't update your UI.

    Move the work into another method, and call it on a worker thread.  Then use Dispatcher.Begin invoke and a lambda to marshal the update back to the UI thread.

     
        private void button1_Click(object sender, RoutedEventArgs e)  
        {  
          ThreadPool.QueueUserWorkItem(OtherWork);  
     
        }  
     
        private void OtherWork(object o)  
        {  
          for (int i = 0; i < 100; i++)  
          {  
             
     
            Thread.Sleep(10);  
            Dispatcher.BeginInvoke(() => progressBar1.Value = i);  
          }  
     
          Dispatcher.BeginInvoke(() => progressBar1.Visibility = Visibility.Collapsed);  
        } 
    Tuesday, May 17, 2011 11:08 PM
  • private void button1_Click(object sender, RoutedEventArgs e)
    {
    ThreadPool.QueueUserWorkItem(OtherWork);
    }
    private void OtherWork(object o)
    { string a;
    for (int i = 0; i
    100; i++)
    {
    ...
    a=textbox1.text;
    ...
    Thread.Sleep(10);
    Dispatcher.BeginInvoke(() => progressBar1.Value = i);
    }
    Dispatcher.BeginInvoke(() => progressBar1.Visibility = Visibility.Collapsed);
    }

    Why this code doesn`t work?
    On a=textbox1.text "Invalid cross-thread access" error apears. What should I do to "a" assign a value of textbox1.text?
    Thursday, May 19, 2011 6:34 PM
  • Anything involving the UI needs to be inside the BeginInvoke
    Thursday, May 19, 2011 6:52 PM
  • The Textbox is also a UI element.  You cannot update any UI element from a non UI thread.
    Thursday, May 19, 2011 7:01 PM
  • But i only need to take text from textbox. I don`t update it.
    Thursday, May 19, 2011 7:10 PM
  • But i only need to take text from textbox. I don`t update it.

    Anything that accesses a UI element(your textbox in this case) must be done on the UI thread. Whether its get or set or whatever.
    Thursday, May 19, 2011 7:24 PM
  • Can you show sample how it can be realized?
    Saturday, May 21, 2011 11:52 AM
  • Moving the call to the textbox.Text property inside your lambda expression should work. Like this:

            private void button1_Click(object sender, RoutedEventArgs e)  
            {  
                ThreadPool.QueueUserWorkItem(OtherWork);  
            }  
     
            private void OtherWork(object o)   
            {   
                string a;   
                for (int i = 0; i <100; i++)   
                {   
       
                    Thread.Sleep(10);   
                    Dispatcher.BeginInvoke(() =>   
                    {  
                        a = textbox.Text;  
                        progressBar1.Value = i;  
                         
                    });  
     
                      
                }  
     
                Dispatcher.BeginInvoke(() => progressBar1.Visibility = Visibility.Collapsed);   
            } 
    Saturday, May 21, 2011 12:26 PM
  • Thank you!!
    Saturday, May 21, 2011 12:50 PM