Overblog Suivre ce blog
Administration Créer mon blog

Présentation

  • : Romagny13 - Du .NET,du pur .NET
  • Romagny13 - Du .NET,du pur .NET
  • : Cycle de progression Faire (quelque chose qui marche) -> comprendre ce que l’on fait/comment cela marche -> pousser plus loin les notions
  • Contact

Recherche

Articles Récents

9 septembre 2007 7 09 /09 /septembre /2007 11:45
[ System.CodeDom ] – exemple de génération de code
Ajouter les deux imports :
using System.CodeDom;
using System.CodeDom.Compiler;
Le but de cet exemple est de présenter avant tout quelques utilisations
 I préparation du code à générer
// 1 Namespace
            CodeNamespace _namespace = new CodeNamespace("MyNamespace");
            // ajout d'imports
            _namespace.Imports.Add(new CodeNamespaceImport("System.Text"));
            // 2 création d'une classe
            CodeTypeDeclaration _class = new CodeTypeDeclaration("Contact");
            _class.Attributes = MemberAttributes.Public;
            _class.Comments.Add(new CodeCommentStatement("mon commentaire 1"));
 
            // a - ajout de fields à la classe
            _class.Members.Add(new CodeMemberField(new CodeTypeReference(typeof(string)), "_contactName"));
           // b - ajout de properties à la classe
            CodeMemberProperty property1=new CodeMemberProperty();
            property1.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            property1.Name = "ContactName";
            property1.Type = new CodeTypeReference(typeof(string));
            property1.HasGet = true;
            property1.HasSet = true;
            // get
            property1.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"_contactName")));
            // set
            property1.SetStatements.Add(new CodeAssignStatement(
                new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"_contactName"),
                new CodePropertySetValueReferenceExpression()));
 
            _class.Members.Add(property1);
            // c - ajout de methodes à la classe
            CodeMemberMethod method1 = new CodeMemberMethod();
            method1.Attributes = MemberAttributes.Public | MemberAttributes.Static;
            method1.ReturnType = new CodeTypeReference(typeof(string));
            method1.Name = "GetContactName";
            method1.Statements.Add(new CodeSnippetStatement("this._contactName="Romagny";"));
            method1.Statements.Add(new CodeMethodReturnStatement(new CodeArgumentReferenceExpression("this._contactName")));
 
II génération du code
 
            StringBuilder stringBuilder = new StringBuilder();
            StringWriter stringWriter = new StringWriter(stringBuilder); 
            CSharpCodeProvider provider = new CSharpCodeProvider();
            //
            CodeGeneratorOptions options = new CodeGeneratorOptions();
            options.BracingStyle = "C";
            options.IndentString = " ";
            provider.GenerateCodeFromNamespace(_namespace,stringWriter, options);
 
            richTextBox1.Text = stringBuilder.ToString();
 

ici je me contente d'afficher le code dans une richtextbox
voici la sortie affichée
namespace MyNamespace
{
 using System.Text;
 
 
 // mon commentaire 1
 public class Contact
 {
   
    private string _contactName;
   
    public string ContactName
    {
      get
      {
        return this._contactName;
      }
      set
      {
        this._contactName = value;
      }
    }
   
    public static string GetContactName()
    {
                this._contactName="Romagny";
                 return this._contactName;
    }
 }
}


http://msdn2.microsoft.com/fr-fr/library/system.codedom(VS.80).aspx
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
17 août 2007 5 17 /08 /août /2007 01:12
Quelques astuces
1 - operateur ternaire
// resultat = condition? valeur retour condition vraie : valeur retour condition fausse
            // ex: int
            int i=11;
            int nResult = (i > 10) ? i * 2 : i;
2 – System.Enum
   Priority priority = Priority.Normal;
            // exemple : retourne "Normal"
            string result = System.Enum.Format(typeof(Priority), priority, "D"); //G ou g renvoie le nom (ex:"Normal"),D ou d renvoie la valeur (ex "2")
            string name = System.Enum.GetName(typeof(Priority), priority);//retourne "Normal
            // retourne les noms dans un tableau de string
            string[] priorities = System.Enum.GetNames(typeof(Priority));
            bool isDefined = System.Enum.IsDefined(typeof(Priority),"High");// retourne true
            // ... voir les autres membres
        

public enum Priority
{
None = 0,
Low = 1,
Normal=2,
High = 3,
NotRemovable = 4
}

3 – Délégués
Appeler plusieurs methods avec un délégué
Récuypèrer la liste des méthodes à appeler grace à System.Delegate
       private delegate void doActionEventHandler();
        private doActionEventHandler doAction;
 
        private void Form1_Load(object sender, EventArgs e)
        {
            //doAction +=new doActionEventHandler(DoFirstAction);
            //doAction +=new doActionEventHandler(DoSecondAction);
            // OU (inference de type)
            doAction += DoFirstAction;
            doAction += DoSecondAction;
 
 
            System.Delegate[] delegatesOfDoAction = doAction.GetInvocationList();
 
          // appeler un delegue de maniere asynchrone , attention le delegue ne doit avoir qu'une seule cible dans ce cas
            doAction.BeginInvoke(null, null);
        }
 
        public void DoFirstAction()
        { }
        public void DoSecondAction()
        { }
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
7 août 2007 2 07 /08 /août /2007 11:46
Bien structurer ses événements

Je me suis inspiré de PropertyChanging pour cet exemple..
 
ClassDiagram1-copie-2.jpg

 
-          1 classe contenant l’EventArgs (héritant de EventArgs)
-          1 classe contenant le délégué (EventHandler)
-          Dans les classes utilisant l’EventArgs :
o   1 délégué
o   1 méthode On… retournant le délégué
-          Références de la classe + abonnement à l’événement (par += et méthode appelée)
1 - Créer une classe contenant l’EventArgs
    public class ContactPropertyChangingEventArgs : EventArgs
    {
        private readonly string propertyName;
 
        public virtual string PropertyName
        {
            get { return this.propertyName; }
        }
        public ContactPropertyChangingEventArgs(string propertyName)
        {
            this.propertyName = propertyName;
       
    }
 
2 - Créer une classe contenant le délégué :
-          Suffixé par Handler
-          Retournera l’objet ayant déclenché l’événement et L’EventArgs 

Note : étant donné l'on passe par l'intermédiaire d'un délégué, il est tout à fait possible de lancer l'événement de manière asynchrone avec BeginInvoke
    public delegate void ContactPropertyChangingEventHandler(object sender, ContactPropertyChangingEventArgs e);
 
3 - Créer une classe qui va utiliser l’événement  
    public class Contact
    {
        public event ContactPropertyChangingEventHandlerContactPropertyChanging;
 
        private int _contactID;
 
        public int ContactID
        {
            get { return _contactID; }
            set
            {
                this.OnContactPropertyChanging("ContactID");
                _contactID = value;
            }
        }
 
        private string _contactName;
 
        public string ContactName
        {
            get { return _contactName; }
            set
            {
                this.OnContactPropertyChanging("ContactName");
                _contactName = value;
            }
        }
 
        private int _contactAge;
 
        public int ContactAge
        {
            get { return _contactAge; }
            set
            {
                this.OnContactPropertyChanging("ContactAge");
                _contactAge = value;
            }
        }
 
        public Contact()
        { }
        public Contact(int contactID,string contactName,int contactAge)
        {
            this.ContactID = contactID;
            this.ContactName = contactName;
            this.ContactAge = contactAge;
        }
 
        public void OnContactPropertyChanging(string propertyName)
        {
            if ((this.ContactPropertyChanging != null))
            {
                this.ContactPropertyChanging(this, new ContactPropertyChangingEventArgs(propertyName));
            }
        }
    }
 
4 - La classe abonnée
       Contact contact;
 
        private void Form1_Load(object sender, EventArgs e)
        {
            contact = new Contact(2, "Bellin", 25);
            // on s’abonne à l’evenement
            contact.ContactPropertyChanging += new ContactPropertyChangingEventHandler(contact_ContactPropertyChanging);
        }
        // la méthode qui sera appelée
        void contact_ContactPropertyChanging(object sender, ContactPropertyChangingEventArgs e)
        {
            MessageBox.Show(e.PropertyName);
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            contact.ContactAge = 26;// birth day !!
        }
 
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
7 août 2007 2 07 /08 /août /2007 01:48
[resgen.exe] –
Générer une classe pour une gestion des ressources « typée »
 
Resgen.exe  est un utilitaire du SDK de Visual Studio (C:/Program Files/Microsoft Visual Studio 8/SDK/v2.0/ par défaut)
Ici je vais générer une classe à partir du fichier de ressources d’une application de manière à accéder très facilement à celles –ci , les fichiers de resources des forms sont egalement exploitables,
 l’interet est d’avoir un accès typé aux ressources et de ce fait bien simplifié et plus rapide que de passer par le ressourceManager
La commande :
resgen  « C:/Documents and Settings/romagny/Mes documents/Visual Studio 2005/Projects /DemoRessources/Properties/Resources.resx” /str:cs
 
Pour plus de renseignements sur les options disponibles :
ou tout simplement dans l’invite de commande
 resgen / ?
Le fichier resources.resources est généré ainsi qu’une classe Resources.cs comprenant des champs static
Au départ j’ai ajouté deux chaines de caracteres dans les ressources du projet (MessageAccueil et MessageFin) on les retrouve bien dans le code généré
Resources.cs
//------------------------------------------------------------------------------
// <auto-generated>
//     Ce code a été généré par un outil.
//     Version du runtime :2.0.50727.1378
//
//     Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
//     le code est régénéré.
// </auto-generated>
//------------------------------------------------------------------------------
 
using System;
 
 
 
///<summary>
///   Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées.
///</summary>
// Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder
// à l'aide d'un outil, tel que ResGen ou Visual Studio.
// Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen
// avec l'option /str ou régénérez votre projet VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
   
    private static global::System.Resources.ResourceManager resourceMan;
   
    private static global::System.Globalization.CultureInfo resourceCulture;
   
    [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
    internal Resources() {
    }
   
    ///<summary>
    ///   Retourne l'instance ResourceManager mise en cache utilisée par cette classe.
    ///</summary>
    [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
    internal static global::System.Resources.ResourceManager ResourceManager {
        get {
            if (object.ReferenceEquals(resourceMan, null)) {
                global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Resources", typeof(Resources).Assembly);
                resourceMan = temp;
            }
            return resourceMan;
        }
    }
   
    ///<summary>
    ///   Remplace la propriété CurrentUICulture du thread actuel pour toutes
    ///   les recherches de ressources à l'aide de cette classe de ressource fortement typée.
    ///</summary>
    [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
    internal static global::System.Globalization.CultureInfo Culture {
        get {
            return resourceCulture;
        }
        set {
            resourceCulture = value;
        }
    }
   
    ///<summary>
    ///   Recherche une chaîne localisée semblable à Bienvenue.
    ///</summary>
    internal static string MessageAccueil {
        get {
            return ResourceManager.GetString("MessageAccueil", resourceCulture);
        }
    }
   
    ///<summary>
    ///   Recherche une chaîne localisée semblable à à bientot.
    ///</summary>
    internal static string MessageFin {
        get {
            return ResourceManager.GetString("MessageFin", resourceCulture);
        }
    }
}
 
 
Utilisation simplissime ,exemple :
lblMessage.Text = Resources.MessageAccueil;
 
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
5 août 2007 7 05 /08 /août /2007 22:49
Surcharger un operateur (operator)

Exemple ici je vais surcharger les operateurs + et – permettant de renvoyer directement le résultat des prix des 2.
Je crées une classe Product
public class Product
    {
        private int _ProductID;
 
        public int ProductID
        {
            get { return _ProductID; }
            set { _ProductID = value; }
        }
 
        private string _ProductName;
 
        public string ProductName
        {
            get { return _ProductName; }
            set { _ProductName = value; }
        }
        private Decimal _UnitPrice;
 
        public Decimal UnitPrice
        {
            get { return _UnitPrice; }
            set { _UnitPrice = value; }
        }
        public Product()
            { }
 
            public Product(int ProductID,string ProductName,Decimal UnitPrice)
            {
                  this.ProductID = ProductID;
                  this.ProductName = ProductName;
                  this.UnitPrice = UnitPrice;
            }
 
        public static Decimal operator +(Product p1,Product p2)
        {
            return p1.UnitPrice + p2.UnitPrice;
        }
        public static Decimal operator -(Product p1, Product p2)
        {
            return p1.UnitPrice + p2.UnitPrice;
        }
    }
 
Utilisation
Ici je n’ai qu’à faire p1 + p2 au lieu de p1.UnitPrice + p2.UnitPrice
 private void button1_Click(object sender, EventArgs e)
        {
            Product p1 = new Product(1, "Chai", 18);
            Product p2 = new Product(1, "Chang", 19);
 
            Decimal result = p1 + p2;
            MessageBox.Show(result.ToString());
        }
 
Une autre utilisation assez connue est celle faite par les Nullables
Celles-ci retournent un type (ex :int )
Ce qui permet de faireNullable<int> intNullable = 10;
        // exemple avec le type int
        public static implicit operator int(intNullable i)
        {
            return i.Value;
        }
        public static explicit operator intNullable(int i)
        {
            return new intNullable(i);
        }
        // avec les generics
        public static implicit operator T?(T value)
        {
            return new T?(value);
        }
 
        public static explicit operator T(T? value)
        {
            return value.Value;
        }
 
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
3 août 2007 5 03 /08 /août /2007 22:21
Avoir plusieurs signatures pour accéder aux éléments d’une collection
 
Peut être avez-vous déjà remarqué que lorsque vous accédez à certaines collections du framework vous avez plusieurs signatures
Exemple avec un DataSet lorsque l’on désire accéder à une DataTable de ce DataSet on fait :
dataSet.Tables[0]
ou
dataSet.Tables[« nomtable »]
Cet article explique comment on peut mettre en place cela
 
 
Dans mon exemple je vais faire en sorte d’avoir deux signatures pour accéder à un élément de la collection
-          Soit par l’index
-          Soit par le contactName
 Collection1.jpg
collection2.jpg
préparation
Ma classique classe contact
 public class Contact
    {
        private int _ContactID;
 
        public int ContactID
        {
            get { return _ContactID; }
            set { _ContactID = value; }
        }
 
        private string _ContactName;
 
        public string ContactName
        {
            get { return _ContactName; }
            set { _ContactName = value; }
        }
 
        private Nullable<int> _ContactAge;
 
        public Nullable<int> ContactAge
        {
            get { return _ContactAge; }
            set { _ContactAge = value; }
        }
 
        public Contact()
        { }
 
        public Contact(int contactID, string contactName, Nullable<int> contactAge)
        {
            this.ContactID = contactID;
            this.ContactName = contactName;
            this.ContactAge = contactAge;
        }
 
        public override string ToString()
        {
            return "ContactID = " + ContactID.ToString() + ",Contactname = " + ContactName + ",ContactAge = " + ContactAge.ToString() ;
        }
 
    }
 
 
I - avec une collection [.NET 1.0]
(je dérive ici ma collection de collectionBase pour ne pas avoir toutes les méthodes à réimplementer mais rien ne vous empeche bien sur de deriver de ICollection,…)
public class ContactCollection : CollectionBase
    {
        public Contact this[int index]
        {
            get
            {
                return (Contact) this.List[index];
            }
        }
 
        public Contact this[string contactName]
        {
            get
            {
                return this.Find(contactName);
            }
        }
 
 
        public void Add(Contact c)
        {
            this.List.Add(c);
        }
        private Contact Find(string contactName)
        {
            foreach (Contact c in this)
                if (c.ContactName == contactName)
                    return c;
 
            return null;
        }   
    }
 
II - avec une liste générique [.NET 2.0]
 
 public class ContactCollection : List<Contact>
    {
        public Contact this[string contactName]
        {
            get
            {
                return this.Find(delegate(Contact c)
                {
                    return c.ContactName == contactName;
                });
            }
        }
    }
 
 
Exemples d’utilisations
Code de la form principale
       ContactCollection Contacts = new ContactCollection();
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Contacts.Add(new Contact(1, "Romagny", 31));
            Contacts.Add(new Contact(2, "Bellin",25));
            Contacts.Add(new Contact(3, "Durand", 50));
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Contacts["Romagny"].ToString());
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Contacts[2].ToString());
        }
 

Un dernier point les properties à la compilation sont converties en méthode (comme on peut le constater avec Reflector) : 
exemple ici avec la classe héritant de CollectionBase
       public Contact get_Item(string contactName)
        {
            return this.Find(contactName);
        }
        public Contact get_Item(int index)
        {
            return (Contact)base.List[index];
        }
 
get.jpg
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
10 juillet 2007 2 10 /07 /juillet /2007 23:53
[.NET 2.0] trier et filtrer avec les generics
I – Filtrer
Le filtre consiste à comparer chacun des elements de la liste par rapport à une condition (exemple StarstWith(« A »)),selon que cette condition est est remplie ou non ,true ou false indique en retour si l’objet en cours doit etre ajouté à la liste résultat
1 – avec les méthodes anonymes
 
private void button1_Click(object sender, EventArgs e)
        {
            // 1 avec méthode anonyme
            List<Contact> result = Contacts.FindAll(delegate(Contact oContact)
            {
                return oContact.ContactAge > 20;
            });
            dataGridView1.DataSource = result;
        }
 
2 – avec les Predicates (System.Predicate<T>)
Les Predicate ne sont en fait rien d’autre que des delegues generics, qui attendent une méthode devant respectant la signature attendue , c'est-à-dire retournant un bool et recevant en paramètre un objet du typeT defini explicitement
private void button1_Click(object sender, EventArgs e)
        {
            // 2 avec un Predicate (qui est un delegue)
            // Predicate<T> predicate = new Predicate<T>(bool(T) target)
            Predicate<Contact> predicate = new Predicate<Contact>(FindContacts);
            List<Contact> result = Contacts.FindAll(predicate);
            dataGridView1.DataSource = result;
        }
        public bool FindContacts(Contact oContact)
        {
         return oContact.ContactAge > 20;
        }
 
3 – en passant tout simplement une méthode respectant la signature des predicates
private void button1_Click(object sender, EventArgs e)
        {           
            List<Contact> result = Contacts.FindAll(FindContacts);
            dataGridView1.DataSource = result;
        }
        public bool FindContacts(Contact oContact)
        {
         return oContact.ContactAge > 20;
        }
 
Format de la méthode :
        public bool nommethod(T obj)
        {
         // test
         Return booleen;
        }
 
II Trier
1 – avec les méthodes anonymes
private void button2_Click(object sender, EventArgs e)
        {          
            Contacts.Sort(delegate(Contact x, Contact y)
            {
                return Comparer<string>.Default.Compare(x.ContactName, y.ContactName);
            });
        }
 
2 – avec Comparison<T>
Ici la méthode va servir à comparer deux instances de la liste generic par rapport à un property, le résultat de la comparaison sera soit
0 (equivalents)          -1          1
private void button2_Click(object sender, EventArgs e)
        {
            // Comparison<T> comparison =new Comparison<T>(int (T,T)target);
            Comparison<Contact> comparison = new Comparison<Contact>(SortContacts);
            Contacts.Sort(comparison);
            dataGridView1.DataSource = Contacts;
        }
        public int SortContacts(Contact x, Contact y)
        {
            return Comparer<string>.Default.Compare(x.ContactName, y.ContactName);
        }
 
3 – en passant tout simplement une méthode respectant la signature de comparison<T>
private void button2_Click(object sender, EventArgs e)
        {         
            Contacts.Sort(SortContacts);
            dataGridView1.DataSource = Contacts;
        }
        public int SortContacts(Contact x, Contact y)
        {
            return Comparer<string>.Default.Compare(x.ContactName, y.ContactName);
        }
 
Format de la méthode de tri
La méthode doit retourner un int
Le type K est le type des properties comparés(c’est un type value :int,string,etc.)
        public int nommethod(T x, T y)
        {
            return Comparer<K>.Default.Compare(x.property, y.property);
        }
 
Bien sur finalement et c’est l’objectif on peut combiner le tri et le filtre de manière de plus en plus complexe
Note : Avec Linq To Objects  lorsqu’on effectue un tri (clause Where) le tri est effectué sur la liste retournée en resultat et non sur la liste d’origine
En utilisant les méthodes décrites ici on peut trier aussi une liste autre que la liste d’origine par exemple la liste obtenue après un filtre mais si on utilise un IComparer ou IComparable défni directement dans la classe (ex : dans la classe contact) alors ce sera la liste d’origine qui sera trié, c’est à savoir quand même
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
9 juillet 2007 1 09 /07 /juillet /2007 09:27
Créer un raccourci sur le bureau
 
Ajouter un référence à IWshRuntimeLibrary (située C:WINDOWSsystem32wshom.ocx)
private void CreateShortCut(string fileName)
        {
            string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            WshShell oWshShell = new WshShell();
            IWshShortcut oIWshShortcut = (IWshShortcut)oWshShell.CreateShortcut(Path.Combine(Desktop, Path.GetFileNameWithoutExtension(fileName) + ".lnk"));
            oIWshShortcut.TargetPath = fileName; 
            oIWshShortcut.Save();
        }
 
Utilisation :
CreateShortCut(« C:/Documents and Settings/romagny/Mes documents/monapplication.exe »);
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
7 juillet 2007 6 07 /07 /juillet /2007 20:09
Une classe de tri generic
 
public class GenericComparer<T> : IComparer<T>
    {
        private string propertyName;
        private SorterMode sorterMode;
 
        public GenericComparer(string propertyName, SorterMode direction)
            : base()
        {
            this.propertyName = propertyName;
            sorterMode = direction;
        }
 
        #region IComparer<T> Members
 
        public int Compare(T x, T y)
        {
            if (x == null)
            {
                if (y != null)
                    return -1;
                return 0;
            }
            if (y == null)
                return 1;
            if ((x is T) && (y is T))
            {
                IComparable value1 = x.GetType().GetProperty(propertyName).GetValue(x, null) as IComparable;
                IComparable value2 = y.GetType().GetProperty(propertyName).GetValue(y, null) as IComparable;
 
                if (sorterMode == SorterMode.Ascending)
                    return value1.CompareTo(value2);
                else
                    return value2.CompareTo(value1);
 
            }
            return 0;
        }
 
        #endregion
    }
 
    public enum SorterMode
    {
        Ascending,
        Descending
    }
 
Utilisation
           List<Contact> Contacts = new List<Contact>();
            Contacts.Add(new Contact(1, "Romagny"));
            Contacts.Add(new Contact(2, "Bellin"));
            Contacts.Add(new Contact(3, "Mariz"));
            Contacts.Add(new Contact(4, "Benon"));
            Contacts.Add(new Contact(5, "Felin"));
 
           GenericComparer<Contact> GenericComparer = new GenericComparer<Contact>("ContactName", SorterMode.Ascending);
            Contacts.Sort(GenericComparer);
 
            dataGridView1.DataSource = Contacts;
 
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article
15 juin 2007 5 15 /06 /juin /2007 20:15
Attributs personnalisés
Dans mon exemple je vais simuler un attribut personnalisé de Mapping comme le fait Linq To SQL
1 – Créer une classe pour cet attribut personnalisé
celle-ci doit hériter de System.Attribute
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false)]
public class MappingAttribute : System.Attribute
    {
        private string _Storage;
 
        public string Storage
        {
            get { return _Storage; }
            set { _Storage = value; }
        }
 
        private string _Name;
 
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
 
 
        private bool _isPrimaryKey;
 
        public bool IsPrimaryKey
        {
            get { return _isPrimaryKey; }
            set { _isPrimaryKey = value; }
        }
 
        private bool _CanBeNull;
 
        public bool CanBeNull
        {
            get { return _CanBeNull; }
            set { _CanBeNull = value; }
        }
 
        private string _DBType;
 
        public string DBType
        {
            get { return _DBType; }
            set { _DBType = value; }
        }
 
        public MappingAttribute()
        { }
        public MappingAttribute(string Storage, string Name, bool IsPrimaryKey, bool CanBeNull, string DBType)
        {
            this.Storage = Storage;
            this.Name = Name;
            this.IsPrimaryKey = IsPrimaryKey;
            this.CanBeNull = CanBeNull;
            this.DBType = DBType;
        }
 
 
2 – Utilisation de l’attribut personnalisé que je viens de créer
public class Contact
    {
        private string _ContactName;
 
        [MappingAttribute(Storage = "ContactName", Name = "Name", DBType = "CHAR(150)", IsPrimaryKey = false, CanBeNull = false)]
        public string ContactName
        {
            get { return _ContactName; }
            set { _ContactName = value; }
        }
 
        public Contact()
        { }
        public Contact(string ContactName)
        {
            this.ContactName = ContactName;
        }
    }
 
3 – Récupérer les informations grâce à la reflection durant l’exécution du programme
private void button1_Click(object sender, EventArgs e)
        {
            Contact oContact = new Contact("Romagny");
 
            MessageBox.Show(GetMappingAttributeOfProperty("ContactName").Name);
        }
 
        public MappingAttribute GetMappingAttributeOfProperty(string PropertyName)
        {
            MappingAttribute oMappingAttribute = null;
            System.Reflection.Assembly oAssembly = System.Reflection.Assembly.GetExecutingAssembly();
            foreach(Type oType in oAssembly.GetTypes())
            {
                if (oType.Name == "Contact")
                {
                    foreach (System.Reflection.PropertyInfo oPropertyInfo in oType.GetProperties())
                    {
                        if (oPropertyInfo.Name == PropertyName)
                        {
                            object[] CustomAttributes = oPropertyInfo.GetCustomAttributes(typeof(MappingAttribute), true);
                            oMappingAttribute = CustomAttributes[0] as MappingAttribute;
                        }
                    }
                }
            }
            return oMappingAttribute;
        } 
  
// OU plus rapide
 public MappingAttribute GetMappingAttributeOfProperty(string PropertyName)
        {
            System.Reflection.Assembly oAssembly = System.Reflection.Assembly.GetExecutingAssembly();
            return oAssembly.GetType("AttributsPersonnalises.Contact").GetProperty(PropertyName).GetCustomAttributes(typeof(MappingAttribute), true)[0] as MappingAttribute;
        }
 
Repost 0
Published by Romagny13 - dans C 1.0- 2.0- 3.0
commenter cet article