Я использую MessageBox, предоставляемый WPF Toolkit. И я получаю ошибку
Вызывающий поток должен быть STA, поскольку многие компоненты пользовательского интерфейса требуют этого.
new Thread(new ThreadStart(delegate
{
MessageBox.Show("Opeartion could not be completed. Please try again.","Error",MessageBoxButton.OK,MessageBoxImage.Error);
})).Start();
Как я могу установить ApartmentState в этом случае
Редактирование: Я пытаюсь отобразить MessageBox без модели, используя элемент MessageBox из WPF Toolkit. Пока что код у меня следующий:
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();
}
}
Как и рамки пользовательского интерфейса, как и многие Windows Forms, WPF также навязывает однопоточную модель, что означает, что вы можете получить доступ только к указанному производному потоку DispatcherObject, который его создает. В элементах управления Windows Forms, реализующих интерфейс ISynchronizeInvoke, этот интерфейс предоставляет набор методов, таких как Invoke и BeginInvoke, чтобы навязать контракт общей синхронизации потоков, который мы можем использовать для доступа к элементу управления из другого потока. В WPF мы также имеем подобную возможность, но эти операции выполняются в классе под названием Dispatcher, Dispatcher WPF - это способ разрешить подобную модель синхронизации потоков.
Ниже приведен пример того, как изменить свойство TextBox.Text, когда вызывающая сторона находится в другом потоке:
// Resets textbox text from another thread
textBox.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
textBox.Text = "New text";
}));
РЕДАКТИРОВАНО
Согласно MSDN В WPF существует встроенный модальный MessageBox, но если вы хотите использовать Modeless MessageBox, то вам придется создать пользовательское окно и затем показать его. Создать, показать и вернуть значение из пользовательского Modeless MessageBox не очень сложно. Вы можете посмотреть эту ссылку
Не стоит использовать отдельный поток только для MessageBox. В любом случае, вы можете установить состояние одной квартиры следующим образом...
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();
// 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);
});
}