2017-09-11 3 views
0

J'ai la classe suivante (exposée à COM) que j'utilise comme enveloppe pour afficher les formulaires appelés à partir de VB6.Appel de la méthode Windows Form Show() en utilisant crash de réflexion

public class NetForm : INetForm 
{ 
    public NetForm(Assembly assembly, string name, object[] parameters) 
    { 
     Assembly = assembly; 
     Name = name; 
     CreateInstance(parameters); 
    } 

    private Assembly Assembly { get; set; } 
    private string Name { get; set; } 
    private Form Instance { get; set; } 

    private void CreateInstance(object[] parameters) 
    { 
     Type type = Assembly.GetType(Name); 
     Type[] types = new Type[parameters.Length]; 
     for (int idx = 0; idx < parameters.Length; idx++) 
      types[idx] = parameters[idx].GetType(); 

     ConstructorInfo ci = type.GetConstructor(types); 
     Instance = (Form)ci.Invoke(parameters); 
    } 
    public void Show() 
    { 
     Instance.Visible = true; 
     Instance.Show();  // Crashing 
    } 
    public void ShowDialog() 
    { 
     Instance.ShowDialog(); // Works perfectly 
    } 
} 

public class NetAssembly 
{ 
    public NetAssembly(string fullname) 
    { 
     Init(fullname); 
    } 

    private Assembly Assembly { get; set; } 

    private void Init(string name) 
    { 
     Assembly = Assembly.LoadFrom(name);    
    } 

    public NetForm GetForm(string nameSpace, string name, object[] parameters) 
    { 
     name = string.Concat(nameSpace, ".", name); 
     return new NetForm(Assembly, name,parameters); 
    } 
} 
  1. ShowDialog() fonctionne parfaitement. Show() n'est pas affiché si la propriété Visible n'est pas définie sur True. Mais aussi en le mettant à vrai, le formulaire est partiellement affiché et se bloque après quelques secondes.

J'utilise un UnitTestProject pour le vérifier:

[TestClass] 
public class NetFormUnitTest 
{ 
    [TestMethod] 
    public void ShowTestMethod() 
    { 
     var assembly = new NetAssembly(assemblyFullName); 
     var form = assembly.GetForm(nameSpace, formName, new object[] { "Item1" }); 
     form.Show(); 
    } 
} 

Quelle est la bonne façon d'appeler la méthode Show()?

+1

Je pense que votre formulaire nécessite une pompe de message (comme * Application.Run * crée). La raison de ShowDialog est qu'il crée sa propre boucle de message. Voir https://stackoverflow.com/questions/26741841/how-does-a-modal-dialogs-message-pump-interact-with-the-main-application-messag Voir aussi [this] (https: // stackoverflow. com/questions/44998082/c-sharp-create-form-sur-distinct-thread-from-formless-application) comment créer un thread d'arrière-plan montrant un formulaire (bien sûr, vous devez remplacer le code lié à la création de l'instance de formulaire –

+0

@LB, Application.Run (instance); faites le fonctionner. Veuillez l'ajouter en tant que réponse – ehh

+0

Copie possible de [Comment utiliser la réflexion pour appeler la méthode par nom] (https://stackoverflow.com/questions/3110280/how-to-use-reflection-to-call-method-by-name) –

Répondre

1

Votre formulaire nécessite une pompe de message (comme Application.Run crée). La raison de ShowDialog est qu'il crée sa propre boucle de message.

Donc, l'ajout de Application.Run(formInstance) devrait résoudre le problème.