开发者

Display busyindicator in wpf application

开发者 https://www.devze.com 2023-04-01 08:11 出处:网络
I have a BusyIndicator from the wpf extended toolkit and I\'m running a function that takes a while to complete.If I run the time consuming task in a separate thread, I get a NotSupportedException bec

I have a BusyIndicator from the wpf extended toolkit and I'm running a function that takes a while to complete. If I run the time consuming task in a separate thread, I get a NotSupportedException because I'm attemping to insert objects into an ObservableCollection from that different thread. I don't really want to spend a lot of time refactoring the code, if possible... Is there a way that I can set the visibility of the indicator in a separate thread instead?

EDIT

ThreadStart start = delegate()
  {
      System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
          {
              IsBusy = true;
          }));
   };

new Thread(start).Start();                开发者_如何转开发                
longRunningFunction();

This did not work for me either.


You should be able to use the Dispatcher for things like that. e.g.

Application.Current.Dispatcher.Invoke((Action)(() =>
{
    _indicator.Visibility = Visibility.Visible;
}));

This will cause the code to be run on the UI-Thread.

There is more info (including how to "properly" do this, with CheckAccess and such) on it in the threading model reference.


You cannot access UI controls from a background worker. What you normally do is set the IsBusy to true before you call BackgroundWorker.RunWorkerAync(), then in the BackgroundWorker.RunWorkerCompleted event handler you would set the IsBusy to false. Seomthing like:

Backgroundworker worker = new BackgroundWorker();
worker.DoWork += ...
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
     IsBusy = false;
};
IsBusy = true;
worker.RunWorkerAsync();

You can use the Dispatcher to add items to your ObservableCollection while in the DoWork event hanlder.

EDIT: Here is the complete solution

        private void Button_Click(object sender, RoutedEventArgs e)
    {
        //on UI thread
        ObservableCollection<string> collection;

        ThreadStart start = delegate()
        {
            List<string> items = new List<string>();
            for (int i = 0; i < 5000000; i++)
            {
                items.Add(String.Format("Item {0}", i));
            }

            System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
            {
                //propogate items to UI
                collection = new ObservableCollection<string>(items);
                //hide indicator
                _indicator.IsBusy = false;
            }));
        };
        //show indicator before calling start
        _indicator.IsBusy = true;
        new Thread(start).Start();      
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消