IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Remplacer du texte par un Hyperlink ?


Sujet :

C#

  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut Remplacer du texte par un Hyperlink ?
    Bonjour,

    Je possède un Textblock (WPF), auquel j'ajoute du texte via Inlines.Add();

    Mes textes sont des phrases facilement localisables avec des noms à insérer dedans. Exemple
    La personne #p1 joue au foot
    #p1 is playing football

    Du coup je met toute la phrase dans mon texte, et j'aimerais remplacer juste #p1 par un hyperlink contenant le nom de la personne.

    Y'a-t-il un moyen simple de faire ça ? Ou alors je dois découper le string en fonction de #p1, ajouter la première partie, mettre l'hyperlink puis mettre le reste du texte ? C'est un peu sale de faire ça comme ça et ça deviendrait vite incompréhensible avec plusieurs références à changer dedans.

    À moins que vous ayiez un moyen plus simple de localiser dans ce cas je suis preneur.

    (Je ne savais pas où placer ce post, plutot dans WPF ou dans C# ? ça concerne peu le WPF au final)

    Merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Le plus simple serait de passer par du XAML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    string text = "La personne #p1 joue au foot";
    string link = "<HyperLink NavigateUri=\"blabla\">#1</HyperLink>";
    string xaml = string.Format("<Span>{0}</Span>").Replace("#1", link);
    ParserContext context = new ParserContext();
    context.XmlnsDictionary.Add(string.Empty, "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    Span content = (Span)XamlReader.Parse(xaml, context);
    textBlock.Inlines.Add(content);
    (par contre attention, si le texte d'origine contient "<" ou ">" ça va pas marcher, il faudra les remplacer par "&lt;" et "&gt;")

  3. #3
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut
    Merci, je vais tester ça.

    EDIT:
    Il manque pas un truc dans ton code ? On ne se sert jamais de la variable text, faut le mettre à la place de {0} je suppose
    Idem dans le replace ça serait plutot #p1 ?

    En faisant comme ça avec ces modifs, j'obtiens bien une variable xaml de type:
    "<span>blablablabla<Hyperlink xxx>personne</Hyperlink></Span>"
    Mais au moment d'arriver sur la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Span content = (Span)System.Windows.Markup.XamlReader.Parse(xaml, context);
    j'ai une erreur :
    'Impossible de créer le type inconnu '{http://schemas.microsoft.com/winfx/2006/xaml/presentation}HyperLink'.' numéro de ligne '1' et position de ligne '8

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par PigKey6 Voir le message
    Il manque pas un truc dans ton code ? On ne se sert jamais de la variable text, faut le mettre à la place de {0} je suppose
    Idem dans le replace ça serait plutot #p1 ?
    Oups, oui :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    string xaml = string.Format("<Span>{0}</Span>"; text).Replace("#p1", link);

    Citation Envoyé par PigKey6 Voir le message
    En faisant comme ça avec ces modifs, j'obtiens bien une variable xaml de type:
    "<span>blablablabla<Hyperlink xxx>personne</Hyperlink></Span>"
    Mais au moment d'arriver sur la ligne
    Span content = (Span)System.Windows.Markup.XamlReader.Parse(xaml, context);

    j'ai une erreur :
    'Impossible de créer le type inconnu '{http://schemas.microsoft.com/winfx/2006/xaml/presentation}HyperLink'.' numéro de ligne '1' et position de ligne '8
    Ah oui, en fait c'est Hyperlink, pas HyperLink (pas de majuscule sur le L). C'est un peu perturbant parce que les deux existent dans le framework

    Sinon, je sais pas si ça répond à ton besoin, mais tu peux regarder la propriété attachée TextBlockBehavior.RichText dans la librairie Dvp.NET

    Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
    <TextBlock dvp:TextBlockBehavior.RichText="{Binding LeTexteRicheXaml}" />

    Je te l'avais pas proposé au début parce qu'il me semblait que ce n'était pas encore inclus dans la version actuelle, mais en fait si...

  5. #5
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut
    J'obtiens toujours une erreur :
    Il existe un caractère non valide dans l'encodage donné. Ligne 1, position 107.
    En fonction du texte à afficher je n'ai pas forcément remarqué de similitudes dans les positions

    ça arrive généralement dans la balise qui ferme Hyperlink ou juste après.

    ma variable xaml contient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <Span><Hyperlink Tag=\"119\" NavigateUri=\"afficher_personne_detail_liste\">XXX</Hyperlink> va à <Hyperlink Tag=\"11\" NavigateUri=\"afficher_ville_detail_liste\">Orleans</Hyperlink></Span>
    Je sais pas si ça change quelque chose mais j'ai pas mis {0} mais "+texte+" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    string xaml = string.Format("<Span>" + texte + "</Span>");
    (Je fais les replace après)

    Voici mon code complet (je passe des tableaux pour faire plusieurs liens d'un coup):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public static Span GetXamlHyperlink(string texte, string[] texteAremplacer, string[] texteremplacement, string[] lien, int[] tags)
            {//le texte = texte du message
                //texte a remplacer = #j1, #t1 etc
                //texteremplacement = "José Machin" etc
                //lien = nom de la fonction
                string xaml = string.Format("<Span>" + texte + "</Span>");
                int i = 0;
                while(i<texteAremplacer.Length)
                {
                    string link = texteremplacement[i];
                    if (lien[i].Length > 0)
                    {//On met un lien que si le lien est bien renseigné
                        link = "<Hyperlink Tag=\"" + tags[i] + "\" NavigateUri=\"" + lien[i] + "\">" + texteremplacement[i] + "</Hyperlink>";
                    }
                xaml = xaml.Replace(texteAremplacer[i], link);
     
                i++;
                }
                ParserContext context = new ParserContext();
                context.XmlnsDictionary.Add(string.Empty, "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
                Span content = (Span)System.Windows.Markup.XamlReader.Parse(xaml, context);
     
                return content;
     
            }

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par PigKey6 Voir le message
    Je sais pas si ça change quelque chose mais j'ai pas mis {0} mais "+texte+" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    string xaml = string.Format("<Span>" + texte + "</Span>");
    ça revient au même, mais dans ce cas String.Format ne sert à rien...


    Sinon, j'ai testé ta fonction avec comme indiqué ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var link = GetXamlHyperlink("Bonjour #name", new[] { "#name" }, new[] { "Thomas" }, new[] { "http://www.google.fr" }, new[] { 42 });
    textBlock1.Inlines.Add(link);
    et j'ai pas d'erreur... donc le problème doit être ailleurs. Montre la StackTrace de ton exception

    EDIT: en fait c'est le caractère "à" qui ne passe pas. Si tu mets "&#224;" à la place, ça fonctionne. Mais c'est bizarre, il me semble que normalement on peut sans problème utiliser des caractères accentués

  7. #7
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut
    Oula,

    Le but de la manoeuvre c'est d'avoir un truc facilement localisable alors si il faut gérer chaque lettre accentuée dans plusieurs langues ça va vite devenir horrible.

    Aucun moyen de contrer ceci ?

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Bon, c'est louche cette histoire... si on utilise Load au lieu de Parse, ça fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
                 ...
     
                ParserContext context = new ParserContext();
                context.XmlnsDictionary.Add(string.Empty, "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
                var bytes = Encoding.UTF8.GetBytes(xaml);
                using (var stream = new MemoryStream(bytes))
                {
                    Span content = (Span)System.Windows.Markup.XamlReader.Load(stream, context);
     
                    return content;
                }
    Ça ressemble à un bug dans XamlReader


    Je file corriger le code dans Dvp.NET

  9. #9
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut
    Merci ça s'affiche maintenant, cependant quand je clique dessus ça ne fait rien.

    Dans NavigateUri, il ne suffit pas de mettre le nom de ma fonction ?

    EDIT : ça marche bien en fait pour tous mes liens sauf pour un, je n'arrive pas à voir pourquoi, la fonction est bien publique, RoutedEventArgs et il rentre pas dedans.

    J'ai deux fonctions avec exactement les meme en-tete et une fonctionne et l'autre non, j'arrive pas à voir pourquoi...

    EDIT2: Meme en mode pas à pas, quand je clique il ne fait rien, pourquoi ?
    Voici une partie de la valeur de la variable :
    <Hyperlink Tag=\"949\" NavigateUri=\"afficher_espoir_detail_liste\">Lucca</Hyperlink>

    La fonction existe bien, je comprends pas...

    En fait, après des tests, je m'aperçois que mon lien avec une fonction ne fonctionne pas tout le temps... Je sèche un peu là... Quelles pourraient être les causes de ces liens qui ne fonctionnent pas ?

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Euh, je comprends pas trop ton histoire là... NavigateUri, c'est une URL, pas une fonction. Il n'y a aucune raison que ça marche si tu mets le nom d'une fonction... (du moins en WPF ; pour Silverlight ou WP7, je sais pas)

    La navigation vers l'URL se fait automatiquement si l'Hyperlink se trouve dans un navigation host (NavigationWindow, Frame, ou un navigateur). Sinon tu peux gérer l'évènement Click...

  11. #11
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut
    Oui autant pour moi ceci explique cela

    J'ai donc mis Click et voici le résultat :
    'Échec de la création d'un 'Click' à partir du texte 'afficher_fonction'.' numéro de ligne '1' et position de ligne '84'.
    Je vois le problème je pense :

    Mon textblock se trouve dans un usercontrol, qui est appelé depuis ma page principale. Dans ma page principale je m'occupe de mettre le texte de ce controle, avec justement des liens vers des fonctions qui afficheront d'autres user control.

    En clair, mes fonctions se trouvent dans Form1.cs et mon textblock dans messagerie.xaml, ya moyen que les hyperlink de celui ci renvoient vers des fonctions extérieures à messagerie, qui se trouvent donc dans Form1 ?

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Le problème c'est qu'avec XamlReader tu ne peux pas spécifier un évènement... ça marche seulement dans le XAML compilé par Visual Studio avec un attribut x:Class.
    Par contre, tu peux récupérer le HyperLink dans le Span (il doit se trouver dans la collection Inlines du Span), et t'abonner manuellement à l'évènement Click (tu peux éventuellement passer un tableau de handlers en paramètre de la méthode)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Span content = (Span)System.Windows.Markup.XamlReader.Load(stream, context);
     
    var links = content.Inlines.OfType<HyperLink>().ToArray();
    for(int i = 0; i < links.Length; i++)
    {
        links[i].Click += handlers[i];
    }

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Autre option, plus propre (et plus naturelle si tu travailles en MVVM), c'est de passer par la propriété Command du lien...

  14. #14
    Membre confirmé
    Inscrit en
    Novembre 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 66
    Par défaut
    Merci beaucoup ça fonctionne à la perfection ! ça va me permettre de faire un code facilement localisable et bien maintenable !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Remplacer un texte par un formulaire
    Par robocop333 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 01/05/2008, 15h49
  2. [RegEx] Remplacer un texte par un include
    Par Oprichnik dans le forum Langage
    Réponses: 4
    Dernier message: 24/01/2008, 23h59
  3. [Tableaux] remplacer du texte par des images
    Par elti69 dans le forum Langage
    Réponses: 2
    Dernier message: 12/06/2007, 10h14
  4. Remplacer du texte par une image en css
    Par Seth77 dans le forum Mise en page CSS
    Réponses: 12
    Dernier message: 03/04/2006, 11h57
  5. Remplacer un texte par un autre
    Par Guillaume602 dans le forum C++
    Réponses: 3
    Dernier message: 24/11/2005, 00h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo