Problème "basique" de binding

Problème "basique" de binding - C#/.NET managed - Programmation

Marsh Posté le 08-10-2015 à 19:04:20    

Salut à tous,

 

Je suis débutant en C# (mais je connais quelque peu le Java pour Android par exemple). J'aimerais me familiariser avec le XAML et les possibilités du WPF tel que le Binding.

 

J'aimerais faire une application très simple :

 

- J'écris dans une TextBox et le résultat est copier sur un TextBlock par binding (c'est tout bon, j'ai réussi)

 

- J'aimerais afficher dans un TextBlock le nombre de fois que je clique sur un bouton. Cependant j'aimerais d'une manière particulière pour bien comprendre les mécanismes et les possibilités :

 

J'ai crée une class "Nombre" comme ceci :

 

   public class Nombre
    {
        private int n;

 

       public string Lire
        {
            get
            {
                return n.ToString();
            }
            private set
            {
            }
        }

 

       public Nombre()
        {
            n = 0;
        }

 

       public void inc()
        {
            n++;
        }
    }

 

Elle permet donc d'instancier un objet stockant le nombre 0. Une méthode permet d'incrémenter ce nombre et une propriété en lecture seule permet de récupérer le nombre sous forme de String.

 

Dans ma class principale, j'ai crée et instancié un objet de class Nombre et j'ai crée un événement qui incrémente le compteur lorsque je clique dessus :

 

   public partial class MainWindow : Window
    {
        private Nombre NombreDeClics;

 

       public MainWindow()
        {
            InitializeComponent();

 

           NombreDeClics = new Nombre();
        }

 

       private void button_Click(object sender, RoutedEventArgs e)
        {
            NombreDeClics.inc();
        }
    }

 

A ce niveau là, j'aimerais savoir si le fait d'instancier cet objet comme je l'ai fait est propre ou pas.

 

Ensuite de cela, j'ai inclue dans le XAML la déclaration suivante :

 

   <Window.Resources>
        <local:Nombre x:Key="NombreDeClics"/>
    </Window.Resources>

 

Est-ce que la Key doit correspondre absolument au nom de l'instance?

 

Finalement, j'ai fait un Binding avec l'assistant de propriétés en "Bindant" le "Text" du TextBlock avec la propriété "Lire" de l'instance NombreDeClics, ce qui donne qqch du genre :

 

       <TextBlock x:Name="textBlockCompteur" HorizontalAlignment="Left" Margin="327,247,0,0" TextWrapping="Wrap" Text="{Binding Lire, Mode=OneWay, Source={StaticResource NombreDeClics}}" VerticalAlignment="Top" Width="80"/>

 

Mon souci est le suivant :

 

Le TextBlock prend au démarrage le nombre par défaut de l'instance, soit 0 (si je modifie le constructeur, le nombre du TextBlock change). Cependant, aucune mise à jour si je clique sur le bouton, pourtant l'événement fonctionne très bien et la variable "n" de mon instance est correctement incrémentée. Je pense que mon souci est qu'il s'agit d'une "StaticResource" et donc qu'elle ne peut pas être changée... ce qui me parait tout à fait acceptable.

 

Malheureusement, je lève une exception si je remplace Static par Dynamic... et si j'essaie d'ajouter une "Source de données" à partir d'un objet, rien ne se passe...

 

Est-ce que mon problème est clairement expliqué? Si oui, avez-vous une solution et conseils. Je souhaite avoir un bon feeling avec le WPF pour ensuite faire bien les choses en me basant sur un modèle MVVM. Mais chaque chose en son temps... :)

 

Merci d'avance à tous ceux qui m'aideront!


Message édité par Maxwell1664 le 08-10-2015 à 19:10:17

---------------
Intel Core i7 2600K / Corsair H60 / Asus P8P67 Deluxe / Asus GTX 580 DirectCUII / Corsair Vengeance 1866 MHz 2x4 Go CAS9 / NZXT Phantom rouge et blanc / Seasonic X-850 / Corsair Force Series GT 240 Go / Western Digital Caviar Blue 1 To SATA III / Lite-On
Reply

Marsh Posté le 08-10-2015 à 19:04:20   

Reply

Marsh Posté le 09-10-2015 à 09:41:36    

Up...
 
C'est mon problème qui est mal posé et que vous n'y comprenez rien ou alors vous n'êtes pas forcément plus doué que moi sur ce coup là?!  :sweat:  


---------------
Intel Core i7 2600K / Corsair H60 / Asus P8P67 Deluxe / Asus GTX 580 DirectCUII / Corsair Vengeance 1866 MHz 2x4 Go CAS9 / NZXT Phantom rouge et blanc / Seasonic X-850 / Corsair Force Series GT 240 Go / Western Digital Caviar Blue 1 To SATA III / Lite-On
Reply

Marsh Posté le 09-10-2015 à 15:07:42    

Je dois avouer que ce n'est pas très clair :D

 

La chose qui me choque le plus, c'est : est-ce que tu ne confonds pas Resource et DataContext ? Renseigne-toi sur les deux.

 

Ton binding est relatif à ton DataContext. Ici, il faut l'initialiser dans ton code-behind (vu que tu es pas en MVVM) : this.DataContext = this; dans le constructeur par exemple, pour lier ton contexte à ton instance de classe MainWindow, puis faire un binding genre  : Text="{Binding Path=Nombre.Lire}" en XAML.

 

Tu peux aussi initialiser le contexte dans le constructeur de MainWindow comme :
this.DataContext = NombreDeClics;

 

Ton binding ressemblera donc à :
Text="{Binding Path=Lire}"

 

Ta classe nombre n'implémente pas INotifyPropertyChanged, ton binding ne sera donc pas rafraichi. Ton private set vide sur "Lire" est inutile.

 

Ta classe Nombre est un peu moche. Simplifie-là au max :

 

   public class Nombre
    {
        private int n;
 

 

      public int Valeur
        {
            get
            {
                return n;
            }
            private set
            {
                n=value;
                //implémente INotifyPropertyChanged ici, genre
                RaisePropertyChanged("Valeur" );
            }
        }
 

 

      public Nombre()
        {
            n = 0;
        }
 

 

      public void inc()
        {
            Valeur = Valeur + 1;
        }
    }

 

L'exemple le plus simple qui ressemble à ce que tu veux faire que j'aie trouvé est ici : http://stackoverflow.com/questions [...] ode-behind


Message édité par Tetedeiench le 09-10-2015 à 15:11:21

---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 09-10-2015 à 15:27:24    

Merci pour la réponse.

 

Oui je dois très certainement confondre pas mal de choses, je suis nouveau dans le WPF et dans le C#. Alors le C# ressemble pas mal au Java, donc c'est pas la fin du monde... mais le WPF est quand même plus complet que l'environnement Android que j'ai un peu l'habitude, d'où quelques soucis.

 

Je regarde un cours en ce moment sur le WPF, ça va peut être m'éclairer un peu... semaine prochaine au plus tard je me repenche sur ce problème et je te tiens au courant.

 

Merci encore

 

EDIT : Après quelques heures de cours à voir ce qui est possible avec WPF, j'y vois déjà plus clair! Donc niveau StaticResource, ça se mets à jour uniquement au chargement de la fenêtre, ce qui est bien le comportement que j'obtiens! Bref, je vais déjà digérer ce que j'ai vu aujourd'hui et on verra la semaine prochaine (je viens de finir les resources mais le binding est plus tard!)

 

Si des personnes sont intéressées par ce cours, voici le lien : https://www.youtube.com/playlist?li [...] fSY4-QcJ3l


Message édité par Maxwell1664 le 09-10-2015 à 18:05:37

---------------
Intel Core i7 2600K / Corsair H60 / Asus P8P67 Deluxe / Asus GTX 580 DirectCUII / Corsair Vengeance 1866 MHz 2x4 Go CAS9 / NZXT Phantom rouge et blanc / Seasonic X-850 / Corsair Force Series GT 240 Go / Western Digital Caviar Blue 1 To SATA III / Lite-On
Reply

Marsh Posté le 13-10-2015 à 17:38:19    

Merci c'est tout bon! Pas tout compris à ton exemple mais en regardant sur ton lien de StackOverflow, c'est tout bon!
 
En fait, ce n'est pas super évident au final... bien plus lourd que binder uniquement deux UserControl déjà tout prêt à l'emploi (genre TextBox avec TextBlock par exemple).
 
Merci encore


---------------
Intel Core i7 2600K / Corsair H60 / Asus P8P67 Deluxe / Asus GTX 580 DirectCUII / Corsair Vengeance 1866 MHz 2x4 Go CAS9 / NZXT Phantom rouge et blanc / Seasonic X-850 / Corsair Force Series GT 240 Go / Western Digital Caviar Blue 1 To SATA III / Lite-On
Reply

Marsh Posté le 14-10-2015 à 14:28:18    

Utilisez la balise code svp, c'est affreux à lire comme ça !


---------------
Topic .Net - C# @ Prog
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed