2014-04-22 3 views
0

Fondamentalement, j'ai 2 projets, un formulaire et un contrôle de l'utilisateur.Dépendance circulaire lors de l'ajout de la référence (délégués)

J'ai besoin que les deux soient dans des projets différents, mais le formulaire doit faire référence au contrôle utilisateur car il utilise le contrôle utilisateur. Et le contrôle de l'utilisateur devra se référer au formulaire comme il utilise une des classes de formulaire. Quand j'ajoute le second parce qu'il a besoin du, VS se plaindra de la dépendance circulaire qui est compréhensible. Comment puis-je résoudre ceci?

+0

Pouvez-vous extraire les classes non-UI du projet Forms et créer une DLL? –

+0

Créez un troisième projet qui contient tout * le formulaire et le contrôle utilisateur. Vous n'obtiendrez jamais vos builds pour fonctionner correctement sans cela. –

Répondre

2

Logiquement, le formulaire devrait dépendre du contrôle de l'utilisateur. Vous pouvez créer une interface pour remplacer le formulaire dans le projet de contrôle utilisateur, puis demander au formulaire d'implémenter cette interface.

Exemple de projet de contrôle utilisateur;

public interface IForm 
{ 
    string MyString { get; } 
} 

public class MyUserControl : UserControl 
{ 
    public IForm Form { get; set; } 

    private void ShowMyString() 
    { 
      String myString = Form.MyString; 
      ... 
    } 
} 

Exemple de projet Formulaire

public class MyForm : Form, IForm 
{ 
    public MYString { get "My String Value"; } 
} 
0

Vous devez séparons votre code, son jamais une bonne idée d'avoir une référence à un ensemble d'application, si vous essayez de le réutiliser à l'avenir, les applications exe devrait aller avec le contrôle. Alors, prenez la classe du projet de formulaire et déplacez-la vers le projet de contrôle ou créez un projet de bibliothèque, placez la classe dessus et référencez-la à partir de votre contrôle et de vos projets d'applications.

1

Je pense que la cause première de votre problème est que vous n'avez pas séparé vos soucis entre le formulaire et le contrôle correctement.

Puisque vous avez un contrôle (un peu générique), il ne devrait pas dépendre du formulaire. Toute la logique du contrôle devrait résider dans le contrôle lui-même. Le formulaire ne doit contenir que le contrôle: ajoutez-le, définissez les champs publics, appelez les méthodes publiques, etc. toute autre chose est une violation de l'encapsulation.

Parfois, les contrôles peuvent avoir besoin de savoir des choses sur leur forme parent. Dans ce cas, je suggérerais quelque chose d'aussi simple que d'ajouter un champ Parent au contrôle enfant.

Si vous avez besoin de quelque chose de plus spécifique à partir du formulaire, vous pouvez toujours ajouter une interface; L'interface doit uniquement répertorier les éléments dont le contrôle a besoin à partir du formulaire. Par exemple, si vous avez besoin de la taille, vous pouvez ajouter:

public interface IControlParent { 
    int Width { get; } 
    int Height { get; } 
} 

De cette façon, vous voyez clairement les dépendances (ce que les besoins de contrôle de la société mère), et si les changements de type parent/contrat, vous n » Vous devez en faire autant pour changer votre classe de contrôle.

0

Vous devez utiliser un événement (délégué). Supposons que dans votre projet de formulaire, vous avez créé une classe: Form1. Et à l'intérieur du contrôle utilisateur, vous avez défini UserControl1. UserControl1 doit instancier et appeler une méthode de Form1:

public class Form1 
{ 
    public void Execute(string sMessage) 
    { 
     Console.WriteLine(sMessage); 
     Console.ReadLine(); 
    } 
} 

UserControl1:

public class UserControl 
{ 
    public Func<object, object> oDel = null; 

    public void Execute() 
    { 
     oDel?.Invoke("HELLO WORLD!"); 
    } 
} 

Et de la classe instancier UserControl, appelons-le ParentClass:

public class ParentClass 
{ 
    public void Execute() 
    { 
     UserControl oUserControl = new UserControl(); 
     oUserControl.oDel = Form1Action; 
     oUserControl.Execute(); 
    } 

    public object Form1Action(object obj) 
    { 
     string sObj = Convert.ToString(obj); 

     Form1 oForm = new Form1(); 
     oForm.Execute(sObj); 

     return null; 
    } 
} 

Cette approche donne la responsabilité de gérer un événement à la classe de haut niveau.