The calling thread must be STA, because many UI co

2019-08-08 05:08发布

I am using the MessageBox provided by WPF Toolkit. And I get the error

The calling thread must be STA, because many UI components require this

new Thread(new ThreadStart(delegate
{
    MessageBox.Show("Opeartion could not be completed. Please try again.","Error",MessageBoxButton.OK,MessageBoxImage.Error);
})).Start();

How can I set the ApartmentState in this case

Edit: I am trying to display a modeless MessageBox using MessageBox control of WPF Toolkit. So far the code I have is as follows:

void SomeFunction()
{
// calls to some UI, and processing and then

var th = new Thread(new ThreadStart(delegate
                                        {
                                           MessageBox.Show("Opeartion could not be completed. Please try again.",
                                                "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                                        }));

                                        th.SetApartmentState(ApartmentState.STA);
                                        th.Start();
                                    }
}

3条回答
看我几分像从前
2楼-- · 2019-08-08 05:51
// enable unit test to mock a dispatcher
var dispatcher = Dispatcher.CurrentDispatcher;
if (Application.Current != null)
{
    // use the application dispatcher if running from the software
    dispatcher = Application.Current.Dispatcher;
}

if (dispatcher != null)
{
    // delegate the operation to UI thread.
    dispatcher.Invoke(
        delegate
        {
            MessageBox.Show("Opeartion could not be completed. Please try again.","Error",MessageBoxButton.OK,MessageBoxImage.Error);
        });
}
查看更多
闹够了就滚
3楼-- · 2019-08-08 05:56

Like the frames of the user interface, like many Windows Forms, WPF also imposes a single threading model, which means you can only access a specified derivative DispatcherObject thread that creates it. In Windows Forms controls that implement the interface ISynchronizeInvoke, this interface exposes a set of methods such as Invoke and BeginInvoke to impose a contract common thread synchronization we can use to access a control from another thread. In WPF, we also have that kind of thing, but these operations are involved in a class called Dispatcher, Dispatcher WPF is the way to allow this kind of thread synchronization model.

The following is an example of how to modify the TextBox.Text property when the caller is in a different thread:

// Resets textbox text from another thread
textBox.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
    textBox.Text = "New text";
}));
查看更多
Deceive 欺骗
4楼-- · 2019-08-08 05:56

EDITED

According to MSDN There exists builtin modal MessageBox in WPF but if you want to use Modeless MessageBox then you have to create custom window and then show it. Creating, showing and and returning value from custom modeless MessageBox is not very tough. You can see this link

It is not wiser to use different thread for messagebox only. Anyway you can set single apartment state by following...

  Thread th = new Thread(new ThreadStart(delegate
  {
    MessageBox.Show("Opeartion could not be completed. Please try again.", "Error",MessageBoxButtons.OK,MessageBoxImage.Error);
  }));

  th.ApartmentState = ApartmentState.STA;
  th.Start();
查看更多
登录 后发表回答