Aujourd'hui j'ai eu une jolie petite érreur qui m'a légèrement embétté car je n'ai rien trouvé d'intéréssant sur le net ...
Scénario:
Dans la conception de mon logiciel j'ai eu à un moment la possibilité de séparer 2 fenêtres WinForm dans 2 threads différents : le premier thread est celui dans lequel s'exécute la form principale de l'application, et le second est crée avec un BeginInvoke sur une methode anonyme ...
Jusque là tout va bien, c'est nikel ce que je voulais, mais dans cette nouvelle fenêtre, crée à partir de AsyncExecuteWizard j'ai voulu afficher un FolderBrowserDialog, et c'est là que j'ai eu ma suprise : il n'y avais dans le FolderBrowserDialog que les bouttons, mais pas le TreeView perméttant d'accéder aux dossiers. Pourtant mon application était bien en STAThread ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 public override void ExecuteWizard() { MethodInvoker async = new MethodInvoker( delegate { try { AsyncExecuteWizard(); } catch (Exception ex) { DreamShield.IDE.Elements.Dialogs.ExecutorErrorDialog.RaiseErrorDialog(ex); } }); async.BeginInvoke(null, null); }
Astuces
La seule astuce que j'ai trouvé pour palier à ce problème et d'avoir dans AsyncExecuteWizard une référence à la form principale de l'application. Ensuite à partir de cette form l'on fait un mainForm.Invoke(fonction_appellant_le_FolderBrowserDialog);.
Seulement, si l'on appelle simplement le Invoke, le thread ( le 2e, pas celui de la form principale ) est bloqué et le paint de la 2e form n'a plus lieu, il faut donc faire encore un BeginInvoke ...
et là, le FolderBrowserDialog fonctionne correctement...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 mainForm.BeginInvoke(new MethodInvoker(delegate { if(folderBrowserDialog.ShowDialog(_la_2e_form) == DialogResult.OK) { } }));
Je ne sais pas si c'est la solution la plus simple, mais n'ayant pas trouvé de réele solution sur le net, j'espère qu'elle pourra un jour aider quelqu'un
NB: pour ceux qui voudrait savoir ce "bug" est du à COM en STAThread ... le FolderBrowserDialog ne peut pas créer d'instance des interfaces du Shell de Windows sur un autre Thread que le premier ... je n'ai pas voulu éssayer avec MTAThread car toutes les pages que j'ai trouvé sur l'explication de l'utilité de l'attribut du Thread préconisent l'utlisation de STAThread dès que l'on fait du WinForms
Edit: Même situation avec un OpenFileDialog ...
Partager