2009-10-07 9 views
1

Je souhaite ajouter des fonctionnalités personnalisées à tous mes contrôles ET mes formulaires. J'ai créé un MyControl de classe, et il n'y a pas de problème juste faire:.NET: Hérite de MyControl for Windows.Forms

MyControl : Control 

puis laisser mes commandes héritent de MyControl. Cependant, je veux que mes formulaires aient la même fonctionnalité, et comme Form hérite de ContainerControl, de Scrollable Container et de THEN Control, je devrais créer mes propres versions de tous ces fichiers pour qu'ils utilisent MyControl, ce qui semble inefficace.

Y a-t-il un moyen de contourner ce problème? Je ne peux pas utiliser une interface, et je ne veux pas créer une copie de la classe appelée MonFormulaire avec les mêmes fonctionnalités que MyControl

Répondre

2

Qu'est-ce que vous cherchez est soit l'héritage multiple (qui n'existe pas dans .net, with no plans to change that), ou la mise en œuvre de l'interface par défaut, alias DII (qui pourrait exister dans une future version de .net)

À ce jour, il n'y a malheureusement pas de solution propre à ce problème, et le mieux est de créer deux classes de base. Cependant, vous pouvez partager le code dans une troisième classe auxiliaire, de sorte que seul le code de la colle soit dupliqué, pas l'implémentation réelle. En fonction de la fonctionnalité que vous essayez d'obtenir, une autre technique utile consiste à créer une seule classe en transmettant un objet (un formulaire ou un contrôle) dans son constructeur et en ajoutant les fonctionnalités supplémentaires dont vous avez besoin. Cependant, vous ne pourrez pas accéder aux membres protégés du contrôle/formulaire de cette manière.

Here est un lien qui traite de votre problème.

+0

Merci. En fait, je ne cherche pas d'héritage en double, même si j'ai ce problème en ce moment Im content que les créateurs Java/.NET aient choisi d'ignorer l'héritage multiple – Rolle

+0

@Rolle: Je suis curieux de savoir pourquoi vous êtes heureux de l'ignorer . Si vous êtes intéressés, voici ce qu'ils ont fait: http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85562.aspx – Brann

+0

J'ai eu une fois une très réelle rencontre avec le "problème du diamant" dans un projet C++ plus important, qui nous a obligé à réécrire beaucoup de code à un stade avancé. En général, je pense qu'à un certain niveau, votre cerveau est susceptible de faire mal quand vous faites un IM si vous ne savez pas très bien comment votre application va se comporter depuis le début, et je trouve que vous ne le faites pas souvent. – Rolle

0

Je pense que la seule façon de le faire est avec

MyForm : Form

Peut-être utiliser une interface plus des méthodes d'extension pour réduire autant que possible la duplication de code.

0

Si tout ce que vous voulez faire est d'ajouter des méthodes supplémentaires, vous pouvez créer des méthodes d'extension qui sont des méthodes qui semblent faire partie d'un certain objet, mais qui ne le sont pas.

Vous pouvez déclarer un comme ceci:

void MyMethod(this Control obj, string foobar); 

Vous pouvez ensuite appeler cette méthode comme une autre méthode de la classe de contrôle:

myButton.MyMethod("baz"); 

Cependant, si vous souhaitez remplacer les méthodes virtuelles, jouer avec les internes de la classe, etc alors il n'y a pas grand-chose que je pourrais vous aider.

1

Vous n'avez pas beaucoup de choix ici car l'héritage multiple n'est pas supporté.

  1. Utiliser des méthodes d'extensions sur le contrôle

  2. réimplémentez dans MonFormulaire ce que vous avez fait dans MyControl.

Pour 2.vous pouvez créer une interface, par exemple IMyControl, et une classe auxiliaire qui l'implémente, comme MyHelperControl : IMyControl. Puis dans MyControl et MyForm implémente IMyControl mais utilise un MyHelperControl privé et mappe tous les membres de l'interface pour appeler de cette aide, de cette façon vous avez seulement un vrai code à gérer.

interface IMyControl { 
    void A(); 
} 

class MyHelperControl : IMyControl { 
    void A() { 
     // your implementation here 
    } 
} 

class MyControl : Control, IMyControl { 
    private MyHelperControl _myHelper; 
    void A() { 
     _myHelper.A(); 
    } 
} 

class MyForm : Form, IMyControl { 
    private MyHelperControl _myHelper; 
    void A() { 
     _myHelper.A(); 
    } 
} 
+0

La question dit qu'il ne peut pas utiliser une interface, même si je ne vois pas pourquoi il ne pouvait pas – MusiGenesis

+0

Peut-être que le "ne peut pas" était parce qu'une interface me dupliquerait le code? C'est pourquoi j'ai compris –

1

Une chose que vous pouvez faire est d'avoir vos formulaires héritent d'une forme « maître » personnalisé qui contient une instance de MyControl, comme ceci:

public partial class MasterForm : Form 
{ 
    private MyControl _MyControl = new MyControl(); 

    public MasterForm() 
    { 
     InitializeComponent(); 
    } 

    public void Method1() 
    { 
     _MyControl.Method1(); 
    } 
} 

Cela signifie dupliquer toutes les signatures de méthode de MonContrôle dans MasterForm (ou tous ceux dont vous avez besoin dans votre formulaire, au moins), mais au moins le code de méthode lui-même ne serait pas dupliqué.

public partial class Form1 : MasterForm 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Method1(); 
    } 
} 

Cette approche évite d'utiliser une interface, bien que je suis curieux de savoir pourquoi exactement vous ne pouvez pas utiliser une interface ici.

+0

@MusicGenesis: Je pense que le PO peut utiliser un inter face, mais veut éviter la duplication du code. – Brann

+0

@Brann: Eh bien, il a dit "je ne peux pas utiliser une interface". – MusiGenesis

+0

Je voulais dire que MyControl ne peut pas être simplement une interface, car il a besoin d'implémenter du code. Merci pour toutes les réponses! – Rolle