Rentre un texblock cliquable

Résolu/Fermé
Photoshoper Messages postés 90 Date d'inscription jeudi 11 décembre 2014 Statut Membre Dernière intervention 2 mai 2019 - 4 févr. 2017 à 20:16
Photoshoper Messages postés 90 Date d'inscription jeudi 11 décembre 2014 Statut Membre Dernière intervention 2 mai 2019 - 8 févr. 2017 à 12:50
Salut tout le monde!
j'ai un petit problème avec mon petit programme, je débute en C# et je rencontre pas mal de difficulté en ce moment...


J'aimerai pouvoir rentre un textblock cliquable, ou par exemple quand je clique dessus ça m'affiche du contenu sur un autre textebox, je ne sais si cela est possible avec un textbloc j'aimerai vraiment avoir votre avis, merci d'avance.

3 réponses

Bonsoir

attention tu parles de TextBlock et de TextBox, ce ne sont pas les mêmes contrôles et le TextBlock n'existe qu'en WPF (pas en WinForm).

Donc je pars du principe que tu travailles en WPF et que tu veux bien copier le contenu d'un TextBox vers un TextBlock. Le problème d'utiliser "le click" c'est que ça va entrer en conflit avec le fait de sélectionner le TextBox avec la souris, alors je te montre avec le click droit (y a le double click aussi).


Dans le mode design de ta Window, tu places ces 2 contrôles.
Dans la fenêtre propriétés, tu leur donnes un nom chacun, pour l'exemple
tbxSaisie et tbkSortie.

Dans la fenêtre propriété, en haut à droite, il y a un petit éclair, en cliquant dessus tu passes à la fenêtre Evénements.
Tu choisis le MouseRightButtonUp de tbxSaisie et tu doubles click dans la zone de saisie.
Cela a 2 effets:
  • dans le xaml:
    <TextBox x:Name="tbxSaisie" Height="23" TextWrapping="Wrap" Text="TextBox" Width="120" MouseRightButtonUp="tbxSaisie_MouseRightButtonUp"/>
    on voie que l’évènement MouseRightButtonUp a pour abonnement tbxSaisie_MouseRightButtonUp
  • dans le cs, la méthode du même nom est crée, et Visual Studio t'y place.


Là il ne te reste plus qu'à mettre
        private void tbxSaisie_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            tbkSortie.Text = tbxSaisie.Text;

        }

Quand j'étais petit, la mer Morte n'était que malade.
George Burns
1
Photoshoper Messages postés 90 Date d'inscription jeudi 11 décembre 2014 Statut Membre Dernière intervention 2 mai 2019 6
Modifié par Photoshoper le 4/02/2017 à 22:31
Merci beaucoup
oui il s'agit bien d'un WPF désolé de ne pas être aussi clair dans la présentation de mon problème...
Ce n’étais exactement pas ça mais, cela m'a été d'une grande aide...pour tous savoir je l'est applique sur deux textbox,
 private void saisi_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            saisi.Text = tbxSaisie.Text;
            sortie.Text = saisi.Text;
        }

et cella a marché à merveille merci beaucoup je vais pouvoir terminer ce petit programme...
0
et voilà, hier je me suis dit que je n'allais pas t'en mettre plein la tête avec le MVC et donc le binding et paf tu me montres que j'aurais peut être du.

C# est un langage tout objet, je mets tout en italique parce que ça ne plait pas à tout le monde, voir ici.
WPF est optimisé pour le binding.
Langaege objet et binding donc MVC.

Ce sont des notions un peu compliquées quand on débute, mais si on prend la peine de s'en imprégner ça vaut vraiment le coup:
  • au final c'est plus facile à coder parce que le langage est pensé comme ça.
  • c'est aussi plus simple à maintenir.
  • si un jour tu veux rafraichir l'interface, sans toucher aux algorithme, il n'y aura quasiment que le xaml à modifier.


Je te montre avec ton cas, crée un projet qui s'appelle "Test WPF Cs" et colle ces codes pour essayer.
D'abord il faut un objet (ou des objets ou une collection d'objets...), donc une classe (à coller dans un fichier cs dedié)

namespace Test_WPF_Cs
using System.ComponentModel;
{
    class DonneesAPhotoshoper:INotifyPropertyChanged
    {
         <summary>
         Initialise les données avec un texte d'accueil dans la saisie
         </summary>
         <param name="TexteInit">Texte d'accueil</param>
        public DonneesAPhotoshoper(string TexteInit)
        {
            TexteSaisie = TexteInit;
        }

        public string TexteSaisie { get; set; }//xn--proprit-gyab de base sans variable interne, mais ça pourrait si on le voulait

        public string TexteSortie { get; private set; }// set est privé, la valeur ne peut être renseigné que par la classe.

        public string TexteEnMajuscule { get;private set; }//pour te montrer un traitement quelconque

         <summary>
         Valide le texte saisi
         </summary>
        public void ValideTexte()
        {
            TexteSortie = TexteSaisie;
            TexteEnMajuscule = TexteSaisie.ToUpper();
            LancePropertyChanged("TexteSortie");//je notifie que TexteSortie a changé
            LancePropertyChanged("TexteEnMajuscule");//je notifie que TexteSortie a changé

            //xn--0ca la place des 2 au dessus notifications du peux aussi essayer de décommenter celle-ci dessous
            //LancePropertyChanged("");
        }

         <summary>
         L'objet doit implémenter INotifyPropertyChanged et surtout le faire vivre, comme ça "l'extérieur" sera notifié quand une valeur change
         </summary>
         <param name="Propriete"></param>
        private void LancePropertyChanged(string Propriete)
        {
            if (this.PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(Propriete));
        }

         <summary>
         L'objet doit implémenter INotifyPropertyChanged et surtout le faire vivre, comme ça "l'extérieur" sera notifié quand une valeur change
         </summary>
       public event PropertyChangedEventHandler PropertyChanged;

    }
}


voici le xaml complet
<Window x:Class="Test_WPF_Cs.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding}" Loaded="Window_Loaded"><!--Avec DataContext="{Binding}" je signale que les données de la window viendront du binding-->

    <Grid Name="grid" DataContext="{Binding .}"><!--Avec DataContext="{Binding .}" je précise que les controles contenus dansle grid, on le même binding que le contenant du grid-->
        <TextBlock TextWrapping="Wrap" Text="{Binding Path=TexteSortie, Mode=OneWay}" Height="40" Margin="67,11,202,269"/> <!--Avec Text="{Binding Path=TexteSortie, Mode=OneWay}" je définis que ce textblock est bindé sur la propriété TextSorite et comme elle est en lecture seule, il ne peut marcher que dans un sens : Source vers contrôle-->
        <TextBox TextWrapping="Wrap" Text="{Binding Path=TexteSortie, Mode=OneWay}" Height="40" Margin="67,68,202,212"/>
        <TextBox TextWrapping="Wrap" Text="{Binding Path=TexteEnMajuscule, Mode=OneWay}" Height="40" Margin="67,113,202,167"/>
        <TextBox x:Name="tbxSaisie" TextWrapping="Wrap" Text="{Binding Path=TexteSaisie,UpdateSourceTrigger=PropertyChanged}"  Height="40" MouseRightButtonUp="tbxSaisie_MouseRightButtonUp" Margin="67,180,202,100"/> <!--Avec UpdateSourceTrigger=PropertyChanged je précise que la source sera mise à jour en cours de frappe, par défaut c'est quand le controle perd le focus-->
    </Grid>
</Window>


et ceci est à mettre dans le cs de mainWindows
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            lesDonnees = new DonneesAPhotoshoper("Veuillez saisir votre texte");//il faut initiliser les données
            this.DataContext = lesDonnees;//et appliquer le binding
        }

        private void tbxSaisie_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            lesDonnees.ValideTexte();
        }



La critique plus fréquente est que ça fait plus de lignes code.
Oui, mais on en est plus à manquer de quelques ko pour un exécutable.

Par contre chacun a bien son job défini.
  • MainWindows (xaml + cs) gère la vue
  • la classe gère le contrôleur.
  • pour le modèle est bien la classe pourra écrire ou importer les données d'une base de données, d'un xml, csv, json, excel etc...


En plus là je te montre avec du texte, mais si tu saisies des booléens, des nombres, des dates ou des durées, en respectant le format de ton pc (symbole décimal, le sens des jours des mois et des années..) et bien le binding convertit pour toi sans code supplémentaire.

Enfin INotifyPropertyChanged est bien sûr utile au binding pour savoir quand mettre à jour l'affichage, mais il peut aussi servir à d'autres objets.
Par exemple si l'objet Accelerateur passe de 50 à 60% et bien l'objet Injection peu réagir à PropertyChnaged et augmenter le débit.
Quand j'étais petit, la mer Morte n'était que malade.
George Burnsusing System.ComponentModel;
0
Photoshoper Messages postés 90 Date d'inscription jeudi 11 décembre 2014 Statut Membre Dernière intervention 2 mai 2019 6
5 févr. 2017 à 16:10
Merci encore pour cela, surtout n’hésitez vraiment pas à m'en mettre plient la tête...
j'ai eu un petit problème au niveau du code, avec les balises
 <summary></summary>

se trouvent dans la classe, si non le reste à bien marché mais je n'est malheureusement pas put testé la solution...ça me laisse pas mal de questions à vous poser.
Si ça ne vous dérange pas
0
Ha oui, il semble que les balises de coloration aient viré les ///

Donc devant
<summary>

</summary>
<param etc...

Il faut 3 ///
Dis moi si tu peux tester ensuite.
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
0
Photoshoper Messages postés 90 Date d'inscription jeudi 11 décembre 2014 Statut Membre Dernière intervention 2 mai 2019 6
8 févr. 2017 à 01:04
salut le code à bien marché merci encore cela m'aide d'avantage je vous remercie... puis -je vous poser quelques questions?
0
Utilisateur anonyme
8 févr. 2017 à 05:40
Bonjour,

Une des règles du forum est de n'avoir qu'un thème par fil, donc si ça concerne le textbox cliquable, oui tu peux poster ici, sinon marque le sujet résolu et poste une nouvelle question.
0
Photoshoper Messages postés 90 Date d'inscription jeudi 11 décembre 2014 Statut Membre Dernière intervention 2 mai 2019 6
8 févr. 2017 à 12:50
merci encore :D
0