Le thread appelant doit être STA, car de nombreux composants UI nécessitent ce WPF

J'utilise le MessageBox fourni par wpf Toolkit . Et j'ai l'erreur

Le thread appelant doit être STA, car de nombreux composants d'interface utilisateur l'exigent

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

Comment puis-je définir l'ApartmentState dans ce cas

Modifier: J'essaie d'afficher un MessageBox modeless en utilisant le contrôle MessageBox de wpf Toolkit. Jusqu'à présent, le code que j'ai est le suivant:

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();
                                    }
}
0
La raison pour laquelle je veux démarrer un nouveau thread est parce que, la boîte à message doit être non modale.
ajouté l'auteur xaria, source
Pourquoi lancez-vous un nouveau fil juste pour montrer une boîte de dialogue? Il serait préférable de signaler votre thread d'interface utilisateur existant et de le montrer. Résoudrait automatiquement votre problème.
ajouté l'auteur Jon, source
wpf "> stackoverflow.com/questions/4183622/…
ajouté l'auteur Klaus78, source
@Jon je suis entièrement d'accord, il n'y a absolument aucune raison de faire tourner un nouveau fil pour afficher une boîte de message. Même si c'était un dialogue qui fait quelque chose qui pourrait bloquer ce fil, je ne proposerais toujours pas un nouveau fil - je suggérerais d'utiliser le Dispatcher.
ajouté l'auteur erodewald, source

3 Réponses

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

Il n'est pas plus sage d'utiliser un thread différent pour la boîte de message uniquement. Quoi qu'il en soit, vous pouvez définir l'état d'un appartement en suivant ...

  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
ajouté
La documentation indique que l'ApartmentState doit être défini avant threadStart. SO que cela signifie que je ne peux pas utiliser la fonction anonyme?
ajouté l'auteur xaria, source
Je reçois toujours l'erreur: Une exception non gérée de type "System.InvalidOperationException" s'est produite dans WindowsBase.dll Informations supplémentaires: Le thread appelant ne peut pas accéder à cet objet car un thread différent le possède.
ajouté l'auteur xaria, source
S'il vous plaît voir mon edit
ajouté l'auteur xaria, source
@ Pallob Je l'obtiens à l'instruction MessageBox.Show. Je suppose que vous utilisez le System.Windows.MessageBox. Je souhaite utiliser le message boîte à outils WPF. Avez-vous essayé avec ça?
ajouté l'auteur xaria, source
@xaria avant de commencer, vous pouvez définir l'état de l'appartement. vérifier la réponse éditée
ajouté l'auteur Md Kamruzzaman Sarker, source
@xaria quel objet utilisez-vous? Vous devez utiliser Method Invoker. Affiche le code que vous écrivez pour accéder à l'objet et le nom et le type de l'objet (de contrôle).
ajouté l'auteur Md Kamruzzaman Sarker, source
J'ai vérifié le code que vous donnez. Cela n'a aucun problème. Il fonctionne sur mon sans aucune erreur. Savez-vous quelle ligne de code donne l'erreur, puis donnez cette ligne de code. Je pense qu'il donne une erreur sur cette partie//appelle à une interface utilisateur, et le traitement, puis
ajouté l'auteur Md Kamruzzaman Sarker, source
@CodingBarfield: Et comment cela ferait-il que son nouveau thread soit en STA?
ajouté l'auteur Grzegorz W, source
Rappelez-vous que vous ne pouvez définir ApartmentState qu'une seule fois pour chaque thread. Je le définirais en définissant: [STAThread] public static void Main ()
ajouté l'auteur CodingBarfield, source

Comme les cadres de l'interface utilisateur, comme de nombreux Windows Forms, wpf impose également un modèle de thread unique, ce qui signifie que vous ne pouvez accéder qu'à un thread DispatcherObject dérivé spécifique qui le crée. Dans les contrôles Windows Forms qui implémentent l'interface ISynchronizeInvoke, cette interface expose un ensemble de méthodes telles que Invoke et BeginInvoke pour imposer une synchronisation de thread commun de contrat que nous pouvons utiliser pour accéder à un contrôle d'un autre thread. Dans WPF, nous avons aussi ce genre de chose, mais ces opérations sont impliquées dans une classe appelée Dispatcher, Dispatcher wpf est le moyen d'autoriser ce type de modèle de synchronisation de threads.

Voici un exemple de comment modifier la propriété TextBox.Text lorsque l'appelant se trouve dans un thread différent:

// Resets textbox text from another thread
textBox.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
    textBox.Text = "New text";
}));
0
ajouté
// 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);
        });
}
0
ajouté