2017-06-30 5 views
1

J'ai un problème avec le dialogue MessageBox, normalement, le MessageBox gèlera et bloquera les fenêtres, et montrera sur le dessus des fenêtres courantes jusqu'à ce que l'utilisateur cliquent sur le bouton de messagebox, mais j'ai le the messagebox ne peut pas bloquer et geler les fenêtres courantes sur VSTO bouton rubanComment geler la fenêtre de perspectives sur VSTO?

private async void BtnTest_Click(object sender, RibbonControlEventArgs e) 
{ 
    MessageBox.Show("before"); 

    var task = await DoSomethingAsync(); 

    MessageBox.Show("after"); 
} 

private async Task<bool> DoSomethingAsync() 
{ 
    await Task.Delay(1000); 
    return true; 
} 

le premier MessageBox peut geler les fenêtres, mais le second ne peut pas, après enquête je l'ai trouvé causé par l'await, quand j'attendre jusqu'à ce DoSomethingAsync fini, la deuxième MessageBox sera normalement geler et bloquer les fenêtres en cours

private void BtnTest_Click(object sender, RibbonControlEventArgs e) 
{ 
    MessageBox.Show("before"); 

    var task = DoSomethingAsync(); 
    task.Wait(); 
    var result = task.Result; 

    MessageBox.Show("after"); 
} 

mais je ne veux pas bloquer l'interface utilisateur Office Outlook Robbin, donc je veux exécuter le DoSomethingAsync asynchrone, quelqu'un sait comment y remédier?

+0

Alors que cela signifie? la deuxième boîte de message est montrée, mais vous pouvez toujours interagir avec la fenêtre principale d'Outlook même la boîte de message est montrée? –

+0

@DmitryStreblechenko, oui, vous avez raison –

+0

Cela signifie que la boîte de message n'est pas correctement parented - Cast Application.ActiveWinow à IOleWindow et appelez IOleWindows :: GetWindow pour obtenir la fenêtre HWND. Vous pouvez ensuite l'utiliser pour afficher la boîte de message. –

Répondre

0

Vous pouvez exécuter un thread secondaire en utilisant la méthode Thread.Start à la place:

using System.Threading; 

Thread thread = new Thread(new ThreadStart(WorkThreadFunction)); 
thread.Start(); 

où la méthode WorkThreadFunction doit ressembler à la suivante:

public void WorkThreadFunction() 
{ 
    try 
    { 
    // do any background work 
    } 
    catch (Exception ex) 
    { 
    // log errors 
    } 
} 

Je vous recommande aussi spécifier la fenêtre parent gérer à la méthode Show. Vous pouvez convertir une instance de la classe Inspector ou Explorer en l'interface IOleWindow qui fournit la fonction GetWindow qui récupère un handle vers l'une des fenêtres participant à l'activation sur place.

Ensuite, vous pouvez créer une instance de l'interface IWin32Window qui peut être transmis à la méthode Show:

public class WindowWrapper : System.Windows.Forms.IWin32Window 
{ 
    public WindowWrapper(IntPtr handle) 
    { 
     _hwnd = handle; 
    } 

    public IntPtr Handle 
    { 
     get { return _hwnd; } 
    } 

    private IntPtr _hwnd; 
} 
+0

Fenêtre IWin32Window = Control.FromHandle (Process.GetCurrentProcess(). Handle); MessageBox.Show (fenêtre, "après"); mais cela ne fonctionne toujours pas –

+0

Je ne pense pas que cela soit dû à l'absence du propriétaire IWin32Window, car le premier MessageBox peut verrouiller la fenêtre Outlook Email Item actuelle avec succès –

+0

Avez-vous essayé d'utiliser la méthode 'Thread.Start' au lieu de tâches? –