none
TextBox dans un User Control avec l'erreur (textbox1.text est inaccessible en raison de son niveau de protection)

    Discussion générale

  • Bonjour à vous tous,

    Je suis quelqu'un qui travaille beaucoup en vb.net.

    j'ai essayé le C# et  je suis bloqué à un problème de débutant

    Voilà,

    J'ai un User Control dans lequel j'ai un TextBox1. avec un clic sur un bouton qui n'est pas sur le même User Control, Je veux chargé une valeur dans le Textbox1 qui vient d'un autre TextBox qui n'est pas sur le même user Control. et j'ai toujours l'erreur  (textbox1.Text est inaccessible en raison de son niveau de protection)

    Avez-vous une solution svp?


    H.B

    dimanche 3 décembre 2017 04:48

Toutes les réponses

  • Bonjour Haroun.B,

    Par défaut, dans un UserControl les contrôles ont une portée private, donc accessible uniquement au sein de la classe du UserControl. 

    Vous pouvez ajouter une propriété pour accéder à ce contrôle (en lecture seule, ou avec la possibilité de lui mettre une valeur). 

    Ajoutez une propriété dans le UserControl :

    public TextBox TextBox1
    {
        get
        {
            return this.textbox1;
        }
        set
        {
            textbox1 = value;
        }
    }

    Maintenant, vous pouvez accéder à textbox1 depuis l'extérieur de votre UserControl via la propriété TextBox1.

    Cordialement,

    mardi 5 décembre 2017 13:25
  • Bonjour,

    Bon, on est optimiste, la personne qui a posé la question va venir nous dire si la réponse lui a permis de résoudre son problème ...

    jeudi 14 décembre 2017 16:03
  • Merci pour votre réponse. Malheureusement cela ne marche pas car on a l’erreur de déclaration en double du textbox1

    Plus d'effort svp ! 


    H.B

    vendredi 15 décembre 2017 05:02
  • Bonjour,

    Alors, c'est qu'on a fait une erreur de casse.

    On doit avoir :

    private textBox1;
    public TextBox1
    {
       get{}
       set{}
    }

    Celui avec une minuscule est local (private), celui avec une majuscule sera appelé depuis l'extérieur (public).

    D'ailleurs, j'ai mis une version abrégée pour simplifier, mais ça peut s'employer tel quel auquel cas on ne mettra pas le champ local (le private textBox1);

    Comme c'est proposé, la procédure événementielle à l'extérieur va appeler :

    userControl1.TextBox1.Text = TextBoxSource.Text;

    Mais en définitive, ce qu'on veut passer, c'est surtout une chaîne de caractères, j'imagine ?

    Donc on pourra avoir une propriété texte.

    Dans le contrôle :

    private string intitule; public string Intitule { get { return intitule; } set { intitule = value; TextBox1.Text = value; } }

    private TextBox TextBox1();


    Dans le code appelant

    UserControl1.Intitule = TextBoxSource.Text;

    Comme je l'ai fait là, si on fait une saisie dans le TextBox1 du contrôle utilisateur il ne se passe rien, on ne peut pas récupérer le texte. J'ai fait ça dernièrement avec des Label, plus appropriés pour cet usage. Avec un TextBox il faudra prévoir de modifier la propriété, soit depuis TextBox1_TextModified, soit depuis le code d'un bouton.

    Le champ local peut aussi être déclaré avec un caractère de soulignement :

    private string _Intitule;
    public string Intitule
    {
      get
      {
        return _Intitule;
      }
    
      set
      {
         _Intitule = value;
      }
    }

    Toutefois les dernières versions de C# ont tendance à dénoncer ça comme une erreur.

    A signaler une macro : taper "prop" suivi de la touche tabulation fera apparaître différents champs entre lesquels on passera, si mes souvenirs sont exacts à l'aide de la touche tabulation :

    - le type

    - le nom de la propriété

    - et me semble-t-il encore quelque chose.

    Mais ceci va générer la syntaxe abrégée, donc si on veut initialiser le contenu d'un contrôle du contrôle utilisateur comme dans l'exemple que j'ai proposé, ça ne va pas forcément tout fournir.

    L'intérêt d'une propriété, par rapport à un champ public, c'est qu'on peut ne mettre qu'un des deux accesseurs selon les besoins de l'application : si on veut que la propriété puisse être modifiée mais pas lue depuis l'extérieur on mettra le set mais pas le get. Plus souvent on initialise la propriété en même temps que le contrôle utilisateur, donc c'est le constructeur du contrôle utilisateur qui va initialiser la propriété (le champ local), et on ne mettra pas le set.

    C'est donc l'habitude de créer plutôt une propriété qu'un champ public, ce qui permet de modifier ses accesseurs ultérieurement si le besoin en apparaît.

    Attention, dernièrement, j'ai déclaré une propriété de type DateTime dans un contrôle utilisateur, l'application n'a pas pu démarrer, et donc pas non plus me signaler d'erreur. Alors, j'ai plutôt créé une propriété de type texte, à laquelle je passe l'expression de la date sous forme de chaîne de caractères.





    • Modifié Gloops vendredi 15 décembre 2017 05:52
    vendredi 15 décembre 2017 05:41
  • M. Arthur LeMeur, Merci bien de votre intérêt à ma question. 

    Voici maintenant le problème avec votre façon;

    j'ai l'erreur suivante

    "Une exception de type 'System.NullReferenceException' s'est produite dans WebAtelierCs02.dll mais n'a pas été gérée dans le code utilisateur"

    Encore plus d'effort stp

    Moi, il me faut savoir comment échanger des données entre deux user control en C# (Je suis bloqué)

    Je vous donne la solution en VB.NET (En VB.Net, je suis expert)

    Donc, notre besoin c’est de récupérer le contenu du txtenvoi dans txtreception

    txtenvoi  et le Bouton btnenvoi se trouvent dans le user control UC_Envoi.ascx

    txtreception se trouve dans user control UC_Reception.ascx

    Les deux user control (UC_Envoi et UC_Reception) se trouvent sur la webforme « Envoi.aspx »

    C’est parti

    I-ajouter une Class.vb dans laquelle on va créer une autre classe d’évènement « btnenvoiEventArgs »

    Dans laquelle il aura un paramètre « paramtxtenvoi »

    Voici le code de la Class « GlobalClass.vb »

    Public Class GlobalClass

        Inherits System.Web.UI.Page

        Public Class btnenvoiEventArgs

            Public paramtxtenvoi As String

        End Class

    End Class

    II- Dans UC_Envoi on va développer deux choses

    1-    Une region Event

    2-    Le code du bouton de déclanchement d’évènement « btnenvoi_Click »  

    Voici le code du UC_Envoi

     

    Imports WebAppVb_Pour_Forum.GlobalClass

    Public Class UC_Envoi

        Inherits System.Web.UI.UserControl

    #Region "Event"

        Public Delegate Sub OnbtnenvoiClick_Event(ByVal sender As Object, ByVal e As btnenvoiEventArgs)

        Public Event btnenvoiClick As OnbtnenvoiClick_Event

    #End Region

     

        Protected Sub btnenvoi_Click(sender As Object, e As EventArgs) Handles btnenvoi.Click

           Dim Args As New btnenvoiEventArgs With {.paramtxtenvoi = txtenvoi.Text}

           RaiseEvent btnenvoiClick(Me, Args)

        End Sub

    End Class

    Donc, on a une delegate d’événement dans la region Event. Et on a un « RaiseEnent »

    III- dans la class UC_Reception il va falloir juste declarer une property de reception de données. Voici le code.

    Public Class UC_Reception
        Inherits System.Web.UI.UserControl
        Public Property property_txtreception_sur_envoi As String
            Get
                Return txtreception.Text
            End Get
            Set(value As String)
                txtreception.Text = value
            End Set
        End Property
    End Class

     

    IV- Dans la Classe de la webForm « Envoi.aspx » Il va falloir developer une partie de code de liaison qui sera exécuté a chaque clique du bouton « btnenvoi » car ce code va utiliser le Handles du bouton en question.

    Voici le code de la Class Envoi

     

    Imports WebAppVb_Pour_Forum.GlobalClass

    Public Class Envoi

        Inherits System.Web.UI.Page

     

        Public Sub idUC_Envoi_actionClick(ByVal sender As Object, ByVal e As btnenvoiEventArgs) Handles idUC_Envoi.btnenvoiClick

            idUC_Reception.property_txtreception_sur_envoi = String.Format(e.paramtxtenvoi)

        End Sub

    End Class

    Voilà, tout ça ce n’est que pour faire échanger les données entre deux user control qui se trouvent sur la même webform

    Le défi maintenant, c’est de comment faire la même chose lorsque les deux User contrôles ne se trouvent pas sur la même WebForm

    A vous de jouer.    

    Fin.

         


    H.B






    vendredi 15 décembre 2017 19:19
  • Bonjour,

    Je n'ai pas regardé trop en détail le code proposé, je retiens juste l'intention générale : nous avons deux contrôles utilisateur avec des zones de saisie, et une saisie sur l'un doit se refléter sur l'autre, c'est bien ça ?

    Il me semble que la direction dans laquelle il faut chercher est de proposer un événement correspondant à une modification d'une propriété sur le contrôle source. Dans le code de cet événement le formulaire contenant pourra modifier une propriété du contrôle cible.

    Je regarde les propriétés de mon contrôle utilisateur, et dans les événements je ne vois rien avec le nom de la propriété.

    A ce que je me rappelle il y a un attribut à ajouter pour que la propriété puisse être initialisée depuis la boîte de dialogue des propriétés du contrôle.

    Mais ce qu'on cherche à faire ce n'est pas ça, c'est déclencher un code lorsque la propriété est modifiée.

    Voyons voir si en posant la question comme ça quelqu'un va savoir répondre.

    jeudi 21 décembre 2017 10:57
  • Bonjour tout le monde,

    Si j'ai bien suivi, nous avons eu droit dans ce fil à des invectives suivies d'une démotivation de l'assemblée. Cela a induit des allongements de délai, je viens d'apprendre que le fil a été sorti du système de statistiques des questions/réponses du forum.
    ça ne signifie pas que nous ne pouvons plus faire avancer la question, mais sans vouloir insister trop je me permets de suggérer que le monde est déjà bien suffisamment violent d'avance pour que nous évitions de jouer à ça entre confrères.

    Histoire de ne pas faire trop traîner les choses en longueur, je vais donc rappeler qu'il est possible de compiler un module en VB.Net et de l'appeler depuis un programme en C#. Sans entrer dans les détails j'ai bien l'impression qu'il s'agira d'un composant utilisateur en VB.Net appelé par une page en C#, je précise que je n'ai pas testé et que je ne pourrai le faire avant quelques semaines. Il y a des règles auxquelles être attentif pour faire ça, mais c'est jouable.
    S'il vous plaît, si ceci est la solution retenue, attention de documenter clairement les choses, pour que l'intérimaire que vous allez appeler un jour pour faire la maintenance s'y retrouve.
    jeudi 4 janvier 2018 12:25