IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Notifier une bindingSource.


Sujet :

C#

  1. #1
    maa
    maa est déconnecté
    Membre éclairé
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Par défaut Notifier une bindingSource.
    Bonjour,

    Je suis actuellement en train de développer un objet "CustomSource" qui prend un objet de type BindingSource en datasource. L'avantage de l'objet BindingSource est qu'il fournit un "curseur" sur les données. Par curseur, j'entends que si plusieurs contrôles sont bindés à une même instance de BindingSource alors le changement de position sur l'un entraine un changement de position sur les autres. Le seul problème que j'ai est que le "curseur" sur les données n'est plus fonctionnel quand mon objet "CustomSource" vient s'intercaler entre le contrôle et l'objet BindingSource. Il me semble qu'il faudrait alors que je capte, dans ma CustomSource, tout changements de position sur le contrôle lié et que je les notifie à la bindingSource. Je ne vois cependant pas comment faire cela. Pourriez-vous m'éclairer ?

    merci d'avance.

    mathmax

  2. #2
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Tu dois modifier la propriété Position du bindingsource en réponse à un evenement particulier de ton controle, par exemple SelectionChanged ou FocusedItemChanged.

  3. #3
    maa
    maa est déconnecté
    Membre éclairé
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Par défaut
    Merci pour ta réponse.

    Le problème que j'ai est que je ne connais pas contrôle depuis ma CustomSource car je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MonControl.Datasource = MaSource;
    Bien sûr je pourrais manuellement ajouter tous contrôle bindés à une propriété collection de ma classe "CustomSource". Mais je préférais récupérer ces contrôles par reflexion. J'aimerais donc récupérer la Form dans laquelle mon objet "CustomSource" a été instancié et récupérer ensuite tous les contrôles de cette Form qui on pour datasource mon instance de CustomSource. Le problème que j'ai est de récupérer la Form dans laquelle mon objet "CustomSource" a été instancié. Saurais-tu comment faire cela ? Ou peut-être tu as une autre idée pour récupérer les contrôles ayant pour datasource mon instance de CustomSource ?

  4. #4
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Le problème que j'ai est de récupérer la Form dans laquelle mon objet "CustomSource" a été instancié
    Cela m'étonne pas que ce soit un problème car c'est impossible, enfin a moins de passer une référence a Form dans le constructeur de ton customSource mais quoi qu'il en soit c'est hyper moche pour un controle de travailler sur son parent.

    J'ai beau me creuser la tête, je vois pas du tout ce qui peut te pousser à vouloir intercaler un objet de ton cru entre un controle et un bindingsource. Je n'ai jamais vu ça nulle part. SI tu pouvais m'expliquer ce que tu cherches à faire...

  5. #5
    maa
    maa est déconnecté
    Membre éclairé
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Par défaut
    J'ai beau me creuser la tête, je vois pas du tout ce qui peut te pousser à vouloir intercaler un objet de ton cru entre un controle et un bindingsource. Je n'ai jamais vu ça nulle part. SI tu pouvais m'expliquer ce que tu cherches à faire...
    Oui excuse moi : cet objet sert à ajouter des propriétés virtuelles aux objets d'une collection (en réécrivant les propertydescriptors) de sorte que l'on pourra afficher à peu près tout ce que l'on veut sur nos objets (des résultats d'expression basées sur des propriétés de nos objets ou même sur les propriété de nos objet propriété etc...).


    Cela m'étonne pas que ce soit un problème car c'est impossible, enfin a moins de passer une référence a Form dans le constructeur de ton customSource mais quoi qu'il en soit c'est hyper moche pour un controle de travailler sur son parent.
    Oui c'est une solution, je passe ma form au constructeur de ma CustomSource... Pourquoi dis-tu que c'est super moche ? As-tu une autre idée ? Passer les contrôles directement ? Ca va être plus lourd d'utilisation... Comment ferais-tu ?

  6. #6
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    En gros l'intérêt donc de cette couche supplémentaire ce serait d'avoir par exemple dans un datagridview des colonnes qui afficheraient le résultat d'un calcul sur les autres propriétés.
    Style par exemple avec un objet fait d'un prix et d'une qte, tu pourrais afficher prix * qte dans une 3e colonne Total.

    Si c'est bel et bien ce que tu cherches à faire je pense qu'il est plus pertinent d'enrichir ton business objet avec des propriétés qui font ce boulot soit directement, soit par héritage ou par encapsulation. Avec ta méthode de couche intermédiaire, tu risques d'avoir certains problèmes sur le tri et le filtrage par le biais de la bindingsource sur tes nouvelles colonnes. La bindingsource est très riche en fonctionnalités, ce sera dur de tout implémenter.

  7. #7
    maa
    maa est déconnecté
    Membre éclairé
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Par défaut
    Oui c'est ça. Et je peux écrire n'importe quelle expressions basée sur les propriété existantes des objets.
    Par exemple :

    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
    17
    public class Company
        {
            public string Name { get; set; }
            public Boss Name { get; set; }
            public List<Worker> Workers { get; set; }
        }
     
        public class Boss
        {
            public string Name { get; set; }
        }
     
        public class Worker
        {
            public string Name { get; set; }
            public float Salary { get; set; }
        }
    Si je binde une datagridView à une List<Company>, je pourrais afficher dans une colonne, le nom des sociétés, dans une autre le nom du patron et dans une troisième le nom de l'employé ayant le plus gros salaire.

    Bien souvent ces "fausses propriétés" n'ont qu'une vocation d'affichage. Je n'ai pas envie de modifier la couche métier pour cela. C'est pour cela que j'ai préféré écrire une vue des objets de ma collection.

    Que proposerais-tu pour récupérer dans ma CustomSource les contrôles bindés à celle-ci ? Pour le moment, j'ai prévu un constructeur de CustomSource qui prend en paramètre un contrôle, puis je regarde si ce contrôle et chacun de ses enfants ont pour datasource mon instance de CustomSource. Qu'en penses-tu ?

  8. #8
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Je partirai sur une propriété List<Controls> dans ton objet que je remplirai après construction.
    Avec une methode telle que AddGridView() ou tu pourrais profiter de setter le datasource de la grid en meme temps.

    Mais si c'est pour un datagridView il existe d'autres possibilités pour ça, tu as le virtual mode qui génère un évenement CellValueNeeded dans lequel tu peux spécifier la valeur d'une cellule non liée au datasource.
    Par ailleurs, quand tu dois binder, utilise BindingList<> Au lieu de List<>, ça fournit plus de fonctionnalités.

    Par ailleurs si tu es un développeur pro et que tu as besoin d'une grid avancée, utilise Xtragrid (<-- excellent), telerik ou Infragistic. Bien sur faudra payer.

  9. #9
    maa
    maa est déconnecté
    Membre éclairé
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Par défaut
    Je partirai sur une propriété List<Controls> dans ton objet que je remplirai après construction.
    Avec une methode telle que AddGridView() ou tu pourrais profiter de setter le datasource de la grid en meme temps.
    Oui c'est bonne une idée.

    Mais si c'est pour un datagridView il existe d'autres possibilités pour ça, tu as le virtual mode qui génère un évenement CellValueNeeded dans lequel tu peux spécifier la valeur d'une cellule non liée au datasource.
    Je ne connais pas ce mode, mais je veux pouvoir setter mes fausses propriétés aussi... c'est à dire définir une méthode qui mette à jour les propriétés de l'objet quand celle-ci est modifiée. Je ne pense pas que je puisse le faire avec l'évenement CellValueNeeded... si ?

    Par ailleurs, quand tu dois binder, utilise BindingList<> Au lieu de List<>, ça fournit plus de fonctionnalités.
    Je m'attendais à cette remarque. En fait c'était juste pour l'exemple. D'ailleurs ma CustomSource implémente IbindingList et informe le contrôle quand la datasource est mise à jour. La datasource peut même implémenter INotifiedCollectionChanged (plus facile à implémenter que IBindingList) et ma CustomSource émettra l'événement ListChanged correspondant. Ce qu'il fait qu'un contrôle est maintenant notifié (indirectement) des changements d'une collection implémentant INotifiedCollectionChanged ce qui n'est pas le cas en windows form quand on binde directement le contrôle à une telle collection...

    Maintenant il va falloir faire l'inverse. Notifier les contrôle d'un changement de position de la BindingSource. Je pense qu'en lançant l'événement ListChanged ça marchera mais avec quel argument pour ListChangedEventArgs (quel ListChangedType) ? Ou alors, plus fastidieux, je bouge maintenant manuellement dans ma CustomSource la position de chacun des contrôles puisque je les ait dans une collection... Qu'en penses-tu ?

  10. #10
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Citation Envoyé par maa Voir le message
    Je ne connais pas ce mode, mais je veux pouvoir setter mes fausses propriétés aussi... c'est à dire définir une méthode qui mette à jour les propriétés de l'objet quand celle-ci est modifiée. Je ne pense pas que je puisse le faire avec l'évenement CellValueNeeded... si ?
    Non, la tu as besoin de CellValuePushed dans laquelle tu vas devoir stocker la valeur entrée par l'utilisateur, ou la rejeter faut voir.

    Citation Envoyé par maa Voir le message
    Maintenant il va falloir faire l'inverse. Notifier les contrôle d'un changement de position de la BindingSource. Je pense qu'en lançant l'événement ListChanged ça marchera mais avec quel argument pour ListChangedEventArgs (quel ListChangedType) ?

    ListChanged sert à notifier d'un changement dans la liste tel un ajout, une suppression ou une modification, le changement de position en soi n'est pas une modification de la liste, la liste ignore tout de ce *curseur* c'est juste une structure de donnée. Perso je ne suis pas sur que ca marche super. Je ne sais pas vraiment quel évenement notifie le control que ce curseur a changé, ca peut être CurrentChanged ou PositionChanged, voire meme propertychanged, je saurai pas dire.

    Citation Envoyé par maa Voir le message
    Ou alors, plus fastidieux, je bouge maintenant manuellement dans ma CustomSource la position de chacun des contrôles puisque je les ait dans une collection... Qu'en penses-tu ?
    Ce serait de la démence, les controles data-aware sont nombreux (combos, grids, listes, navigators) et ce serait sans doute pas évident pour gérer chacun de ces cas de figure manuellement.

    Je suis absolument navré mais j'ai de plus en plus l'împression que ce que tu essaies de faire là, c'est un anti-pattern. En dehors des problèmes d'implémentations que cela te pose(ra) pour les fonctions spéciales (navigation, tri, filtre, recherche, relai d'évenements, synchronisation), tu vas à l'encontre de l'architecture de databinding des windows form.

    Je m'explique, tu souhaites afficher une information qui ne provient pas directement de la source de données, soit c'est un scénario assez courant. Le souci c'est que tu essaie d'intervenir sur un composant standard (le bindingSource) supposé assurer la communication entre une donnée et un controle en l'enrichissant d'une fonctionnalité qui va totalement à l'encontre de son fonctionnement et de son but. C'est une chose.
    Ensuite tu dis vouloir pouvoir setter les propriétés non liées, c'est à dire que tu implémentes une logique métier directement au beau milieu d'un composant de présentation.
    Par ailleurs, si j'ai bien compris, ces objet Source que tu vas créer seront très spécifique à son controle hote et ainsi n'offriront pas beaucoup de réutilisabilité.
    Je sais que quand tu vas lire ça tu vas dire, "encore un de ces boulets avec ses patterns et tout" mais je suis sincèrement persuadé que tu fais fausse route.

    Pour tes colonnes non liées, binde donc tout ce que tu peux à la source original via une bindingsource sans surcouche, et ensuite utilise le mode virtuel et des classes Helper pour te retourner le résultat de la cellule. Si tu ne veux pas créer de nouveaux business objects ou enrichir les existants c'est vraiment tout ce que je peux te conseiller.

    Voilà, excuse moi encore.

  11. #11
    maa
    maa est déconnecté
    Membre éclairé
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Par défaut
    Merci pour tes conseils.

    Je reconnais que bouger les positions des contrôles manuellement est vraiment moches et pas du tout évolutif.

    Je suis d'ailleurs obligé de faire des cas particuliers selon les contrôles pour accéder à la propriété DataSource. En effet l'ancêtre commun à Combobox et DatagridView par exemple est Control et celui-ci ne possède pas de propriété DataSource. Quel dômmage qu'on ne puisse pas dire qu'une classe implémente une interface sans le noter explicitement dans la définition de la classe Je veux dire qu'ici ça serait pratique de créer une interface comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public interface IHasDataSource
    {
         public object DataSource {get; set; }
    }
    et que toutes les classes qui ont effectivement une telle propriété implémente automatiquement cette interface. Vois-tu ce que je veux dire ?

    Je cherche à ce que ma classe intermédiaire soit le plus générique possible pour qu'elle soit réutilisable à volonté :
    - Il faut pouvoir ajouter n'importe quelle propriété virtuelle et n'importe quelle méthode pour mettre à jour les propriétés sous jacentes quand celle-ci est modifié par d'utilisateur.
    - Il faut qu'elle accepte n'importe quel type de datasource : BindingSource, IBindingList, INotifiedCollectionChanged ou encore une IListSource renvoyant IBindingList, INotifiedCollectionChanged.
    - Elle permet aussi de filtrer et de trier les éléments.
    - Je souhaite aussi que ça marche avec tous les types de contrôles. Je ne sais pas si l'utilisation du mode virtuel et de CellValuePush dont tu parles permet cela. C'est spécifique à la DataGridView non ? Comment ferais-tu dans les autres cas ?

    Je ne sais pas vraiment quel évenement notifie le control que ce curseur a changé, ca peut être CurrentChanged ou PositionChanged, voire meme propertychanged, je saurai pas dire.
    oui mais là ça n'est pas utilisable car ma classe n'est pas une BindingSource donc même si j'émets un tel événement, je ne pense pas que les contrôles s'y abonneront... Tu as une autre idée pour notifier les contrôles du changement de position du curseur de la bindingSource ?

    Ensuite tu dis vouloir pouvoir setter les propriétés non liées, c'est à dire que tu implémentes une logique métier directement au beau milieu d'un composant de présentation.
    non je ne crois pas. Je définie simplement quelle propriétés doivent être mise à jour met je laisse la classe le faire à sa manière.

    Sinon tu parles aussi de classes Helper qui pourrait m'aider ? Quelles sont-elles ?

    Encore une fois merci pour tes conseils. Ne t-en excuse surtout pas, ils me sont très utiles.

    mathmax

  12. #12
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Je ne voudrai pas dire une connerie car j'utilise rarement sinon jamais les composants standards windows form. Le mode virtuel n'est pertinent que pour les controles affichant simultanément plusieurs propriétés de leur source, donc forcément pas les combo ni les listbox, ni même les treeview.

    Les classes helper sont comme leur nom l'indique des classes d'aides qui fournissent des méthodes (qui peuvent être statiques) qui servent à assister d'autres classes en amenant des fonctionnalités générales. Une methode externe à ton business object company servant à obtenir l'employé le mieux payé de la société sans le placer directement dans company y trouverait sa place par exemple.
    - Il faut pouvoir ajouter n'importe quelle propriété virtuelle et n'importe quelle méthode pour mettre à jour les propriétés sous jacentes quand celle-ci est modifié par d'utilisateur.
    Je pensais que tu comptais hériter de ta classe source pour fournir les fonctionnalités... Si ce n'est pas le cas comment comptes-tu appeler ces méthodes et ces propriétés, par un delegate?

  13. #13
    maa
    maa est déconnecté
    Membre éclairé
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Par défaut
    Les classes helper sont comme leur nom l'indique des classes d'aides qui fournissent des méthodes (qui peuvent être statiques) qui servent à assister d'autres classes en amenant des fonctionnalités générales. Une methode externe à ton business object company servant à obtenir l'employé le mieux payé de la société sans le placer directement dans company y trouverait sa place par exemple.
    Ok mais je problème c'est qu'on ne peut pas binder directement une méthode d'une classe statique à un contrôle. Donc comment pourrait-elles m'aider ?

    Je pensais que tu comptais hériter de ta classe source pour fournir les fonctionnalités... Si ce n'est pas le cas comment comptes-tu appeler ces méthodes et ces propriétés, par un delegate?
    Oui c'est exactement ça. Tient je te donne un exemple d'utilisation de ma classe :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    CustomSource<Product> source = new CustomSource<Product>();
     
    source.FakeProperties.Add("LowerPrice",
        //"méthode get"
        y =>
        {
            var allPrices = y.Prices;
            if (allPrices.Count == 0)
                return string.Empty;
     
            var lowerPrice = (from p in allPrices
                              orderby p.Amount[Devise] 
                              select p).First();
     
            //on sauvagarde l'instance pour pouvoir la setter.
            source.StoredObject = lowerPrice;
     
            return lowerPrice.ToString(Devise);
        },
        //"méthode set"
        value =>
        {
            source.StoredObj<Price>().Parse(value);
        });

  14. #14
    Membre émérite
    Avatar de shwin
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    568
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2003
    Messages : 568
    Par défaut
    Selon ce que j'ai pu comprendre, tu veux seulement ajouter des column calculer

    Voici ma facon de faire

    Ma classe modele
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    	public class Vehicule
    	{
    		private int _roue;
     
    		public int Roues
    		{
    			get { return _roue; }
    			set { _roue = value; }
    		}
     
    	}
     
    	public class Camion : Vehicule, ICustomTypeDescriptor
    	{
    		public Camion()
    		{
     
    		}
     
    		private string _marque;
     
    		public string Marque
    		{
    			get { return _marque; }
    			set { _marque = value; }
    		}
     
    		private string _couleur;
    		public string Couleur
    		{
    			get { return _couleur; }
    			set { _couleur = value; }
    		}
     
     
    		#region ICustomTypeDescriptor Members
     
    		public AttributeCollection GetAttributes()
    		{
    			return null;
    		}
     
    		public string GetClassName()
    		{
    			return null;
    		}
     
    		public string GetComponentName()
    		{
    			return null;
    		}
     
    		public TypeConverter GetConverter()
    		{
    			return null;
    		}
     
    		public EventDescriptor GetDefaultEvent()
    		{
    			return null;
    		}
     
    		public PropertyDescriptor GetDefaultProperty()
    		{
    			return TypeDescriptor.GetDefaultProperty(this, true);
    		}
     
    		public object GetEditor(Type editorBaseType)
    		{
    			return null;
    		}
     
    		public EventDescriptorCollection GetEvents(Attribute[] attributes)
    		{
    			return null;
    		}
     
    		public EventDescriptorCollection GetEvents()
    		{
    			return null;
    		}
     
    		public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    		{
     
    			VehiculeLePlusLourd newProp = new VehiculeLePlusLourd("nouveauprop");
     
    			PropertyDescriptorCollection props = new PropertyDescriptorCollection(null);
     
    			//foreach (PropertyDescriptor prop in newProps)
    			//  baseProps.Add(prop);
    			props.Add(newProp);
    			return props;
    		}
     
    		public PropertyDescriptorCollection GetProperties()
    		{
    			 return TypeDescriptor.GetProperties(this,true);;
    		}
     
    		public object GetPropertyOwner(PropertyDescriptor pd)
    		{
    			return null;
    		}
     
    		#endregion
    	}
    Mon TypeDescriptor (nouvelle column)
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    	public class VehiculeLePlusLourd : PropertyDescriptor
    	{
     
    		public VehiculeLePlusLourd(string name)
    			: base(name, null)
    		{
    		}
     
     
    		public override string Name
    		{
    			get
    			{
    				return "PlusLourd:Name";
    			}
    		}
     
    		public override string DisplayName
    		{
    			get
    			{
    				return "PlusLourd:DisplayName";
    			}
    		}
     
    		public override object GetValue(object component)
    		{
    			return 1;
    		}
     
    		public override void SetValue(object component, object value)
    		{
     
    		}
     
     
     
    		public override bool CanResetValue(object component)
    		{
    			throw new Exception("The method or operation is not implemented.");
    		}
     
    		public override Type ComponentType
    		{
    			get { throw new Exception("The method or operation is not implemented."); }
    		}
     
    		public override bool IsReadOnly
    		{
    			get { return false; ; }
    		}
     
    		public override Type PropertyType
    		{
    			get { return this.GetType(); }
    		}
     
    		public override void ResetValue(object component)
    		{
    			throw new Exception("The method or operation is not implemented.");
    		}
     
    		public override bool ShouldSerializeValue(object component)
    		{
    			throw new Exception("The method or operation is not implemented.");
    		}
    	}
    Ma source
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    public Form1()
    		{
    			InitializeComponent();
     
    			List<Camion> c = new List<Camion>();
    			Camion vehicule = new Camion();
    			vehicule.Marque = "GM";
     
    			c.Add(vehicule);
    			dataGridView1.AutoGenerateColumns = true;
    			dataGridView1.DataSource = c;
    		}
    Donc ce que tu as de besoin est de ICustomTypeDescriptor et PropertyDescriptor.

    Ceci est seulement a type d'exemple.

    Cependant, tu doit savoir qu'en implémentant ICustomTypeDescriptor, tu perd le designer a cause d'un bug dans le bindingsource

    Voir http://connect.microsoft.com/VisualS...edbackID=95763 pour une description du probleme.

  15. #15
    maa
    maa est déconnecté
    Membre éclairé
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Par défaut
    Oui mais ça nous oblige à implémenter ICustomTypeDescriptor or on n'as pas toujours accès aux source de nos classes... Et puis c'est un peu lourd à implémenter.
    D'ailleurs il y a 2 ou 3 erreurs dans ton implémentation il me semble :

    Tu oublis de reprendre les propriétés existantes du type :
    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
    17
     
                public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
                {
     
                    VehiculeLePlusLourd newProp = new VehiculeLePlusLourd("nouveauprop");
     
                    PropertyDescriptorCollection props = TypeDescriptor.GetProperties(GetType());
     
                    PropertyDescriptor[] newProps = new PropertyDescriptor[props.Count + 1];
     
                    for (int i = 0; i < props.Count; i++)
                        newProps[i] = props[i];
     
                    newProps[props.Count] = newProp;
     
                    return new PropertyDescriptorCollection(newProps);
                }
    GetPropertyOwner doit renvoyer this.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public object GetPropertyOwner(PropertyDescriptor pd)
                {
                    return this;
                }

    Mais c'est vrai que ta méthode présente l'avantage de ne rien avoir à insérer entre la bindingSource et le contrôle.

Discussions similaires

  1. Notifier une jsp!
    Par lilisweety dans le forum Servlets/JSP
    Réponses: 0
    Dernier message: 22/06/2009, 11h01
  2. [Débutant]Miseà jour d'une BindingSource
    Par elsuket dans le forum C#
    Réponses: 3
    Dernier message: 27/03/2009, 16h00
  3. Réponses: 1
    Dernier message: 11/01/2007, 14h20
  4. [vb2005E] Enregistrer une Bindingsource dans une table
    Par moriss dans le forum Windows Forms
    Réponses: 5
    Dernier message: 08/06/2006, 14h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo