2012-05-24 7 views
1

Я использую MessageBox, предоставленный WPF Toolkit. И я получаю ошибкуВызывающий поток должен быть STA, потому что многие компоненты пользовательского интерфейса требуют этого WPF

Вызывающий поток должен быть STA, так как многие компоненты пользовательского интерфейса требуют этого

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

Как я могу установить ApartmentState в этом случае

Edit: Я пытаюсь для отображения немодального 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(); 
            } 
} 
+1

Почему вы начинаете новую нить, чтобы показать диалоговое окно? Было бы гораздо лучше сигнализировать о существующем потоке пользовательского интерфейса и показать его. Автоматически решит вашу проблему. – Jon

+0

http://stackoverflow.com/questions/4183622/the-calling-thread-must-be-sta-because-many-ui-components-require-this-in-wpf – Klaus78

+0

@ Я полностью согласен, есть абсолютно нет причины откручивать новый поток, чтобы отображать окно сообщения. Даже если это диалог, который делает что-то, что может заблокировать этот поток, я все равно не предлагаю новый поток - я бы предложил использовать диспетчер. – erodewald

ответ

0

EDITED

Согласно MSDN Там существует встроенный модальный MessageBox в WPF, но если вы хотите использовать Немодальные MessageBox, то вы должны создать пользовательский и затем показать его. Создание, отображение и возврат значения из пользовательской модели MessageBox не очень сложно. Вы можете увидеть this link

Не разумнее использовать другую тему только для сообщений. В любом случае вы можете установить одно состояние квартиры, следуя ...

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(); 
+0

Помните, что вы можете установить ApartmentState только один раз для каждого потока. Я бы установил его, установив: [STAThread] public static void Main() – CodingBarfield

+0

@CodingBarfield: И как это сделает его новый поток в STA? –

+0

В документации указано, что ApartmentState необходимо установить перед threadStart. SO, что означает, что я не могу использовать анонимную функцию? – xaria

4

Like рамках пользовательского интерфейса, как и многие другие 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"; 
})); 
0
// 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); 
     }); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^