2009-05-21 8 views
1

J'utilise la classe listée ci-dessous pour créer un UserControl enveloppant un ComboBox qui peut accepter une Liste <T> et retourner un objet de type T lorsque la sélection de ComboBox interne est modifiée.L'événement non-abstrait défini dans la classe abstraite n'apparaîtra pas dans Designer pour les classes dérivées

Tout fonctionne correctement dans le code, exactement comme je le souhaite, mais je ne peux plus afficher l'événement SelectedItemChanged dans le concepteur lorsque j'utilise mon contrôle. Cela a bien fonctionné quand la classe de base abstraite n'était pas abstraite, mais j'essaye de condenser 5 contrôles essentiellement en double en un.

Des pièces sans importance ont été coupées.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Windows.Forms; 

namespace UserComboTest 
{ 
    public abstract partial class DropDownList<T> : UserControl where T : class 
    { 
     protected abstract int FindIndex(T item); 
     public abstract void Populate(List<T> items, T defaultItem); 

     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Browsable(true)] 
     public event EventHandler<SelectedItemEventArgs> SelectedItemChanged; 

     private void comboBox_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      if (null != SelectedItemChanged) 
      { 
       SelectedItemChanged(this, new SelectedItemEventArgs(Selected)); 
      } 
     } 

     public class SelectedItemEventArgs : EventArgs 
     { 
      public SelectedItemEventArgs(T selectedItem) 
      { 
       Selected = selectedItem; 
      } 

      public T Selected { get; private set; } 
     } 
    } 

    public class UserDropDownList : DropDownList<User> 
    { 
     protected override int FindIndex(User user) 
     { 
      // find index for item 
     } 

     public override void Populate(List<User> users, User defaultUser) 
     { 
      // populate the list 
     } 
    } 
} 

EDIT: Correction du problème de rupture code. Il s'est avéré que mon espace de noms et mon formulaire s'appelaient UserComboTest. Lorsqu'il a sérialisé le nom de type complet (UserComboTest.UserDropDownList), il a supposé qu'il s'agissait d'un membre ou d'une classe sous le formulaire, et non de l'espace de noms. En d'autres termes, il pensait qu'il cherchait UserComboTest.UserComboTest.UserDropDownList, qui n'existe pas. Renommer le formulaire en UserComboTest.UserComboTestForm a résolu la moitié du problème. Reste toujours le fait que le concepteur n'affiche pas l'événement SelectedItemChanged, et si je l'ai défini manuellement, il est supprimé, donc je dois le définir en dehors de InitializeComponent, ou trouver comment l'obtenir. être sérialisé.

Répondre

2

Généralement, le concepteur de winforms réagit mal aux classes de base abstraites. Vous devez transformer les méthodes abstraites en méthodes virtuelles vides et rendre la classe non abstraite.

+1

actualisé pour voir votre réponse. J'ai supprimé le mien. Vous pouvez mentionner un constructeur protégé ou interne pour restreindre l'utilisation de la classe de base si c'est ce que l'intention est. En outre, lancez NotImplementedException ou NotSupportedException dans les virtuals vides. –

+0

J'y avais pensé, puisque le Designer m'a donné la lèvre avant de ne pas avoir un constructeur public sans arguments. Malheureusement, rendre les deux méthodes virtuelles tout en rendant la classe non abstraite ne laisse pas apparaître l'événement dans le concepteur, et je perds ma vérification à la compilation pour m'assurer que les fonctions sont implémentées. –

Questions connexes