Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1516 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  [C#] Parcours de tous les controles d'une application ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C#] Parcours de tous les controles d'une application ?

n°1711048
nucl3arfl0
Better Call Saul
Posté le 01-04-2008 à 15:30:18  profilanswer
 

Hello,
 
je vous explique un peu le contexte.
L'idée est de simplifier la vie du développeur.
 
Exemple:
 
Générer automatiquement la hierarchie d'une application dans la base de données à partir des Menu présents dans les forms (et page).
Ceci nécessite un parcourt de tous les controles de l'application.
Sauf qu'à l'heure actuel, je ne sais faire un parcourt que d'une form courante.
Il est évidemment probablement qu'une form non instanciée contienne un menu et que je dois également récupérer ce dernier.
 
Alors ma question est simple, comment faire ça (si c'est possible) ?
 
Autre idée, à chaque fois que je "drag'n drop" un menu sur une form, j'enregistre un lien vers cet objet dans un control global de l'application (en mode design).
L'idéal serait d'avoir juste à parcourir les menus stockés dans ce contrôle pour récupérer leur contenu et mettre à jour la base de données.
 
Et là non plus, je ne vois pas comment faire, car les élements n'étant pas instanciés ça coince...
 
Merci pour votre aide  :hello:

mood
Publicité
Posté le 01-04-2008 à 15:30:18  profilanswer
 

n°1711212
MagicBuzz
Posté le 01-04-2008 à 19:20:46  profilanswer
 

Application.GetOpenForms() ou un truc du genre, te retourne une collection des forms ouvertes de ton programme.
 
Si tu veux les forms contenues dans ton assembly, alors il faut les trouver via ce moyen.
Sauf qu'après, je vois pas ce que tu veux en faire, vu que tu peux très bien avoir dans ton code "this.Controls.Add(new Label());" par exemple... (typiquement le cas pour les membres d'un menustrip par exemple)
 

Code :
  1. // Récupération de toutes les "forms" de l'application
  2.            Assembly asm = Assembly.GetExecutingAssembly();
  3.  
  4.            // Parcours de tous les types de l'assembly
  5.            foreach (Type t in asm.GetTypes())
  6.            {
  7.                // Il s'agit d'une form
  8.                if (t.BaseType == typeof(Form))
  9.                {
  10.                    MessageBox.Show(t.Name);
  11.                }
  12.            }


Message édité par MagicBuzz le 01-04-2008 à 19:21:31
n°1711244
nucl3arfl0
Better Call Saul
Posté le 01-04-2008 à 20:06:19  profilanswer
 

Et ce code fonctionne aussi si le type se trouve dans une DLL importée en référence ?
 
Je t'explique un peu le pourquoi de ma demande.
 
Techniquement, on a développé un module de sécurité où l'on attribue des droits sur des actions (qui se trouvent dans les applications).
Seulement, cela implique de créer les actions dans le module de sécurité, et à la longue c'est très lourd et chiant à gérer (notamment pour le développeur).
 
L'idéal serait que le développeur développe normalement, c'est à dire, mets ses MenuStrip, ToolbarStrip dans ses forms, et qu'au moment du login au début de l'application, ça va récupérer tous ses menus et vérifier si la hiérarchie de l'application est à jour dans la base de données. Si c'est pas le cas, on met à jour la BDD.
 
En gros, avoir une génération automatique de la hiérarchie de l'application dans la base de données sans avoir à se casser le cul dans le module de sécurité à ajouter les rubriques et les actions une à une.
 
Si ce n'est pas clair, dis moi, je ré-expliquerai ;)

n°1711249
MagicBuzz
Posté le 01-04-2008 à 20:15:04  profilanswer
 

nucl3arfl0 a écrit :

Et ce code fonctionne aussi si le type se trouve dans une DLL importée en référence ?
 
Je t'explique un peu le pourquoi de ma demande.
 
Techniquement, on a développé un module de sécurité où l'on attribue des droits sur des actions (qui se trouvent dans les applications).
Seulement, cela implique de créer les actions dans le module de sécurité, et à la longue c'est très lourd et chiant à gérer (notamment pour le développeur).
 
L'idéal serait que le développeur développe normalement, c'est à dire, mets ses MenuStrip, ToolbarStrip dans ses forms, et qu'au moment du login au début de l'application, ça va récupérer tous ses menus et vérifier si la hiérarchie de l'application est à jour dans la base de données. Si c'est pas le cas, on met à jour la BDD.
 
En gros, avoir une génération automatique de la hiérarchie de l'application dans la base de données sans avoir à se casser le cul dans le module de sécurité à ajouter les rubriques et les actions une à une.
 
Si ce n'est pas clair, dis moi, je ré-expliquerai ;)


Tu peux récupérer les referenced assemblies de l'assembly courrante, donc je dirais que oui (à condition que tu places ce code dans l'assembly "racine" )

n°1711287
nucl3arfl0
Better Call Saul
Posté le 01-04-2008 à 21:55:04  profilanswer
 

MagicBuzz a écrit :


Tu peux récupérer les referenced assemblies de l'assembly courrante, donc je dirais que oui (à condition que tu places ce code dans l'assembly "racine" )


Oki merci, je testerai ça demain.... misère misère quand même...  :pt1cable:

n°1711389
nucl3arfl0
Better Call Saul
Posté le 02-04-2008 à 09:44:19  profilanswer
 

Hello,
 
bon ça marche en Win (à part si on ajoute des items via le code source et non plus via le mode design), par contre en Web, niet :/

n°1711545
MagicBuzz
Posté le 02-04-2008 à 12:07:05  profilanswer
 

T'as bien changé le test en :

Code :
  1. if (t.BaseType == typeof(WebForm))


:whistle:

n°1711552
nucl3arfl0
Better Call Saul
Posté le 02-04-2008 à 12:30:14  profilanswer
 

Code :
  1. private void findCalendar()
  2.     {
  3.         Assembly asm = Assembly.GetExecutingAssembly();
  4.         foreach (Type t in asm.GetTypes())
  5.         {
  6.             if (t.BaseType == typeof(Page))
  7.             {
  8.                 findCalendarHelper((Page)Activator.CreateInstance(t));
  9.             }
  10.         }
  11.     }
  12.     private void findCalendarHelper(Page p)
  13.     {
  14.         foreach (Control c in p.Controls)
  15.         {
  16.             if (c is Page)
  17.                 findCalendarHelper((Page)c);
  18.             else
  19.             {
  20.                 if (c.GetType() == typeof(Calendar))
  21.                 {
  22.                     Response.Write("<script language=\"JavaScript\">alert('"+c.ID+"');</script>" );
  23.                 }
  24.             }
  25.         }
  26.     }


 
Calendar c'est un exemple évidemment.
Je veux récupérer toutes mes pages, et dans ces pages, je veux récupérer les controles.
Par contre, je pense que ma façon de procéder là, n'est pas bonne. Du moins, il ne faudrait pas que j'utilise Activator.CreateInstance sur le type page.
Une idée ?

n°1711891
MagicBuzz
Posté le 03-04-2008 à 09:26:22  profilanswer
 

J'ai bloqué là dessus aussi.
 
J'ai pas trouvé comment rechercher les contrôles contenus dans une classe lorsque cette dernière n'est pas instanciée.
 
Avec la réflection, j'ai tenté d'aller voir les Properties et les Attributes des pages, mais rien trouvé. Pourtant je pense que c'est plutôt cette piste qu'il faut suivre.
 
D'un autre côté, créer une instance, c'est garantir d'avoir sous la main les contrôles y compris ceux créés avec des "this.Controls.Add()"
 
Bonne chance en tout cas :sweat:

n°1712045
nucl3arfl0
Better Call Saul
Posté le 03-04-2008 à 12:13:15  profilanswer
 

MagicBuzz a écrit :

J'ai bloqué là dessus aussi.
 
J'ai pas trouvé comment rechercher les contrôles contenus dans une classe lorsque cette dernière n'est pas instanciée.
 
Avec la réflection, j'ai tenté d'aller voir les Properties et les Attributes des pages, mais rien trouvé. Pourtant je pense que c'est plutôt cette piste qu'il faut suivre.
 
D'un autre côté, créer une instance, c'est garantir d'avoir sous la main les contrôles y compris ceux créés avec des "this.Controls.Add()"
 
Bonne chance en tout cas :sweat:


Merci.
 
Je me suis renseigné sur le forum MSDN US, et quelqu'un a donné la même idée que j'avais au départ:
 
Parcourir le code source toutes les pages ASPX et récupérer le code "balisé" du contrôle..
Là également, ça pose problème dans le cas d'un menu généré dynamiquement, mais bon, c'est mieux que rien, et ça a l'air de marcher. Quant au temps d'exécution, ça ne se passera qu'au niveau du développeur, donc aucune incidence pour le client.
 
Merci Microsoft qui nous pousse à programmer comme des cochons  :(  
 
Edit: Quant à la reflection, c'était une piste pour le Win, car quand on glisse et dépose le composant dans la form, VS sauvegarde les informations dans le désigner. Ce qui fait que quand tu instancies la form dynamiquement, tu peux récupérer ces attributs.
En revanche, pour le web, ce n'est pas possible. Quand on glisse et dépose le composant dans la page, c'est uniquement le code ASP qui est généré. Et dans ce cas là, l'objet n'est instancié qu'au runtime avec ses attributs.
Et comme dans la reflection tu dois lui passer le type pour l'instanciation, ta page n'hérite que de la classe "System.Web.UI.Page", et cette instanciation te donne qu'une page vierge sans attributs...

Message cité 1 fois
Message édité par nucl3arfl0 le 03-04-2008 à 12:16:46
mood
Publicité
Posté le 03-04-2008 à 12:13:15  profilanswer
 

n°1712338
ixemul
Nan mais sans blague ! ⚡
Posté le 03-04-2008 à 17:57:05  profilanswer
 

nucl3arfl0 a écrit :


Merci.
 
Je me suis renseigné sur le forum MSDN US, et quelqu'un a donné la même idée que j'avais au départ:
 
Parcourir le code source toutes les pages ASPX et récupérer le code "balisé" du contrôle..
Là également, ça pose problème dans le cas d'un menu généré dynamiquement, mais bon, c'est mieux que rien, et ça a l'air de marcher. Quant au temps d'exécution, ça ne se passera qu'au niveau du développeur, donc aucune incidence pour le client.
 
Merci Microsoft qui nous pousse à programmer comme des cochons  :(
 
Edit: Quant à la reflection, c'était une piste pour le Win, car quand on glisse et dépose le composant dans la form, VS sauvegarde les informations dans le désigner. Ce qui fait que quand tu instancies la form dynamiquement, tu peux récupérer ces attributs.
En revanche, pour le web, ce n'est pas possible. Quand on glisse et dépose le composant dans la page, c'est uniquement le code ASP qui est généré. Et dans ce cas là, l'objet n'est instancié qu'au runtime avec ses attributs.
Et comme dans la reflection tu dois lui passer le type pour l'instanciation, ta page n'hérite que de la classe "System.Web.UI.Page", et cette instanciation te donne qu'une page vierge sans attributs...


 
[:ofou] c'est l'hopital qui se fout de la charité là, avec l'usine à gaz que tu veux monter ;)


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°1712395
nucl3arfl0
Better Call Saul
Posté le 03-04-2008 à 19:23:46  profilanswer
 

Moi je me base sur les contraintes qu'on me donne :(
Vaut mieux avoir une usine à gaz qui fonctionne que rien du tout :o
Ah et j'ai déjà retourné le problème en long en large et en travers, j'peux pas faire mieux, le reste ne dépendant pas de moi..

n°1712536
MagicBuzz
Posté le 03-04-2008 à 23:30:58  profilanswer
 

Un truc pas trop crade serait j'imagine quelquechose de ce genre :
 
Projet "Web Control Collection" :

Code :
  1. using System;
  2. using System.Xml;
  3. using System.Web.UI;
  4. using System.Web.UI.WebControls;
  5. using System.ComponentModel;
  6.  
  7. namespace SecurityControls
  8. {
  9.    public class SecurityManager
  10.    {
  11.        public bool CheckVisible(WebControl wc)
  12.        {
  13.            bool display = true;
  14.            XmlDocument dom = new XmlDocument();
  15.            dom.Load(wc.Page.MapPath("rights.xml" ));
  16.            XmlNode ControlSecurity = dom.DocumentElement.SelectSingleNode("control[@id='" + wc.ID + "' and @page='" + wc.Page.AppRelativeVirtualPath + "']" );
  17.            if (ControlSecurity == null) ControlSecurity = dom.DocumentElement.SelectSingleNode("control[@id='" + wc.ID + "' and not(@page)]" );
  18.            if (ControlSecurity != null)
  19.            {
  20.                display = bool.Parse(ControlSecurity.Attributes["display"].Value);
  21.            }
  22.            if (!display) return false;
  23.            return true;
  24.        }
  25.    }
  26.  
  27.    /// <summary>
  28.    /// Summary description for SecurizedControls
  29.    /// </summary>
  30.    [DefaultProperty("Text" ), ToolboxData("<{0}:SecurizedLabel runat='server'></{0}:SecurizedLabel>" )]
  31.    public class SecurizedLabel : Label
  32.    {
  33.        SecurityManager sm;
  34.        public SecurizedLabel()
  35.        {
  36.            sm = new SecurityManager();
  37.        }
  38.  
  39.        protected override void Render(System.Web.UI.HtmlTextWriter writer)
  40.        {
  41.            if (!sm.CheckVisible(this)) return;
  42.            base.Render(writer);
  43.        }
  44.    }
  45.  
  46.    /// <summary>
  47.    /// Summary description for SecurizedControls
  48.    /// </summary>
  49.    [DefaultProperty("Text" ), ToolboxData("<{0}:SecurizedTextBox runat='server'></{0}:SecurizedTextBox>" )]
  50.    public class SecurizedTextBox : TextBox
  51.    {
  52.        SecurityManager sm;
  53.        public SecurizedTextBox()
  54.        {
  55.            sm = new SecurityManager();
  56.        }
  57.  
  58.        protected override void Render(System.Web.UI.HtmlTextWriter writer)
  59.        {
  60.            if (!sm.CheckVisible(this)) return;
  61.            base.Render(writer);
  62.        }
  63.    }
  64. }


 
Projet "Web Site", référençant le premier :

Code :
  1. <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
  2.  
  3. <%@ Register Assembly="SecurizedWebControls" Namespace="SecurityControls" TagPrefix="cc1" %>
  4.  
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  6.  
  7. <html xmlns="http://www.w3.org/1999/xhtml" >
  8. <head runat="server">
  9.    <title>Untitled Page</title>
  10. </head>
  11. <body>
  12.    <form id="form1" runat="server">
  13.        <cc1:SecurizedLabel ID="SecurizedLabel1" runat="server">Test</cc1:SecurizedLabel>
  14.        <br />
  15.        <cc1:SecurizedTextBox ID="SecurizedTextBox1" runat="server">Test</cc1:SecurizedTextBox>
  16.        <br />
  17.        <cc1:SecurizedLabel ID="SecurizedLabel2" runat="server">Test</cc1:SecurizedLabel>
  18.        <br />
  19.        <cc1:SecurizedTextBox ID="SecurizedTextBox2" runat="server">Test</cc1:SecurizedTextBox>
  20.        <br />
  21.        <cc1:SecurizedLabel ID="SecurizedLabel3" runat="server">Test</cc1:SecurizedLabel>
  22.        <br />
  23.        <cc1:SecurizedTextBox ID="SecurizedTextBox3" runat="server">Test</cc1:SecurizedTextBox>
  24.    </form>
  25. </body>
  26. </html>


+ default.aspx.cs tout vide chez moi
 

Code :
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <controls>
  3.     <control id="SecurizedLabel1" display="false"/>
  4.     <control id="SecurizedLabel2" display="true"/>
  5.     <control id="SecurizedLabel2" display="false" page="~/default.aspx"/>
  6.     <control id="SecurizedTextBox1" display="false"/>
  7.     <control id="SecurizedTextBox2" display="true"/>
  8. </controls>


J'ai ça à la racinde de mon site
 
Et ça me permet, via mon fichier XML de décider quels champs s'affichent ou non, en prenant le pas sur ce que je peux tenter de vouloir faire au niveau programmation dans la page.

n°1712538
MagicBuzz
Posté le 03-04-2008 à 23:33:20  profilanswer
 

Mais bon, ça nécessite quand même quelques changements dans le code existant, et surtout, ça n'empêche pas un développeur d'utiliser les contrôles standards plutôt que ceux-ci.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  [C#] Parcours de tous les controles d'une application ?

 

Sujets relatifs
[JAVA] Lancer application Externe et Afficher dans une Frameexecution application au demarrage et avant les autres
Probleme de connection a une base local via Applicationapplication web pour base de connaissance
[SMS] Envoi depuis une application phpMettre une application en "root" sur Linux
VB6 et Application ExcelChanger une application VBA pour un autre language de programmation
Classes DAO (MVC2)[HTA] Taille de fenêtre d'une application HTA
Plus de sujets relatifs à : [C#] Parcours de tous les controles d'une application ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR