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 :

Insertion de blocs "de mots" dans un texte


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Inscrit en
    Octobre 2005
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 26
    Points : 29
    Points
    29
    Par défaut Insertion de blocs "de mots" dans un texte
    Bonjour, j'ai une question un peu difficile à expliquer:

    Je souhaiterais avoir une zone de texte où je pourrai intégrer des blocs "de mots".

    Je vais essayer d'être plus clair, dans un texte "normal" les mots sont divisés en lettres (c'est a dire que l'on peu sélectionner un lettre au milieu d'un mot), mon besoin est de pouvoir définir une portion de ce texte comme un bloc (une entité indivisible) :
    donc quand on clique sur une des lettres d'un mot de ce bloc, il faut que ce soit le bloc entier qui soit sélectionné (idéalement entouré d'un contour).

    Les exemples les plus proches que j'ai pu trouver sont :
    - Lors du publipostage dans Word, pendant la définition du "calque" de création, les mots du masque sont saisissable en entier et non divisible.

    - Lors de la création d'un rapport Reporting Services l'intégration d'un zone de formule dans une zone de texte.

    Mon besoin étant particulièrement difficile a exprimer, mes recherches n'ont malheureusement pas été très fructueuses.

    Je suis conscient que mes explications ne sont peu être pas très clairs, et je serais ravi d'apporter des précisions si besoin.

    Si vous avez des pistes ou des liens je suis preneur.

    Environnement : C#, Framework 4.0 et Winform ou WPF

    D'avance merci de vos réponses

    Dadv


    Ps: plus d'informations dans mes réponses suivante
    Images attachées Images attachées   

  2. #2
    Membre expérimenté
    Avatar de jbrasselet
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2006
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 022
    Points : 1 413
    Points
    1 413
    Par défaut
    Tu dois pouvoir faire ça en javascript. Sur ton onclick, tu récupère l'emplacement du click et et ensuite tu recherches, avant et après, des séparateurs (ton deuxième exemple) et ensuite utilise l'objet range a priori.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai.

  3. #3
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par jbrasselet Voir le message
    Tu dois pouvoir faire ça en javascript. Sur ton onclick, tu récupère l'emplacement du click et et ensuite tu recherches, avant et après, des séparateurs (ton deuxième exemple) et ensuite utilise l'objet range a priori.
    Euh, relis le message : c'est un programme client lourd(Winform et WPF ne suppportent pas le javascript ou alors j'ai raté une évolution )

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  4. #4
    Membre expérimenté
    Avatar de jbrasselet
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2006
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 022
    Points : 1 413
    Points
    1 413
    Par défaut
    Arf oui zut, autant pour moi, j'ouvre les yeux
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Octobre 2005
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Merci de votre réponse,

    Comme indiqué dans mon message, mon environnement est en application Windows et non pas web.

    Le principe du Range est un peu ce que je cherche a avoir (une plage de sélection) mais ce que je n'ai pas expliqué dans mon premier message c'est que cette zone devrait être idéalement un objet (avec des propriétés, méthodes, etc.) et cela même si visuellement il s'agit de texte.

    L'exemple des formules dans reporting services est vraiment exactement ce que je veux avoir.

    L'utilisateur tape du texte au kilomètre, puis double clic sur un bouton qui ira ouvrir une fenêtre spécifique (de calcul ou autre), une fois cette fenêtre validée un bloc de texte viendra s’insérer pour symboliser cette zone de calcul.

    Ultérieurement lors du traitement de cette zone de texte, les résultats des calculs seront inséré.

    Mon approche actuelle s'oriente sur une zone en XML avec des balises spécifique pour les calculs. reste l'aspect visuel, je ne désire pas que l'utilisateur gère du XML mais simplement du texte et des formules.

    J'oriente mes explications sur les calculs car ils sont a mon sens les plus facile a comprendre, mais je garde en tête l'orientation "objet" de la chose.


    édit : page => plage

  6. #6
    Nouveau membre du Club
    Inscrit en
    Octobre 2005
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Voila un début d'approche en WPF

    Dans ma page WPF je met un RichTextBox et à l’intérieur dans un container en ligne, mon objet (ici un control utilisateur)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <RichTextBox Name="rtbFlow" Foreground="#FFF21313">
                <FlowDocument>
                    <Paragraph>
                        <InlineUIContainer>
                            <my:UserControl1 />
                        </InlineUIContainer>
                    </Paragraph>
                </FlowDocument>
            </RichTextBox>
    Ceci peut être fait facilement en code donc pas de soucis.

    Dans mon control utilisateur je met simplement le visuel voulu :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <Grid>
            <TextBlock Text="{Binding Path=Display}" />
    </Grid>

    et dans son code les propriétés dont j'ai besoin

    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
     
    public partial class UserControl1 : UserControl
        {
            public string Display { get; set; }
     
            public int Param1 { get; set; }
            public int Param2 { get; set; }
     
            public int Result { get; set; }
     
            public UserControl1()
            {
                InitializeComponent();
                this.DataContext = this;
            }
        }
    On peux après récupérer la liste des controls utilisateur assez facilement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    var controls = rtbFlow.Document.Blocks.OfType<Paragraph>()
                    .SelectMany(p => p.Inlines.OfType<InlineUIContainer>()
                        .Select(s => s.Child).OfType<UserControl1>());
    Voila on peut écrire et les bloc sont bien unitaire (pas possible d'écrire dedans), par contre d'autres problèmes se posent :
    - Quand on les déplace à la souris ou qu'on les copie colle, les blocs disparaissent (?)

    - Je n'ai pas trouvé le moyen de récupérer les évènements sur les controls, le richtextbox semble les absorber (par exemple le double clique ne fonctionne que sur le richtextbox et cela même si un double clique est défini dans le control utilisateur, pareil pour le contextmenu).

    Si quelqu'un connait un moyen de passer outre les blocages du richtextbox (mais uniquement sur mes controls) je suis preneur.

  7. #7
    Membre habitué Avatar de swif79
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2009
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juillet 2009
    Messages : 79
    Points : 169
    Points
    169
    Par défaut
    Si tu mets la propriété IsDocumentEnabled de ta richtextbox à true ?

  8. #8
    Nouveau membre du Club
    Inscrit en
    Octobre 2005
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Citation Envoyé par swif79 Voir le message
    Si tu mets la propriété IsDocumentEnabled de ta richtextbox à true ?
    Merci cela résout un des problèmes c'est à dire l’interaction avec les controls utilisateur.


    Reste le problème de copier/coller ou de déplacement qui supprime les controls.

    une première réponse se trouve surement ici ou , mais je ne vois pas bien comment interagir avec le DataObject.Copying.

    Edit:

    Petite avancée :

    J'ai réussi a implémenter le DataObject.Copying et a y insérer un control sérialisé.
    Par contre pas moyen d'avoir la version Xaml d'origine pour pouvoir insérer le BON objet (sic).
    Je n'arrive qu'a obtenir le balisage primitif du InlineUIContainer (il ne garde même pas la propriété Name...)


    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
    26
    27
    28
     
    private void rtbFlow_Copying(object sender, DataObjectCopyingEventArgs e)
            {
                var rtb = sender as RichTextBox;
                if (rtb != null)
                {
     
                    UserControl1 uc = new UserControl1();
                    uc.Initialize("Test");
     
                    string ser = System.Windows.Markup.XamlWriter.Save(uc);
     
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        rtb.Selection.Save(memoryStream, DataFormats.Xaml, true);
                        memoryStream.Position = 0;
     
     
                        using (StreamReader streamReader = new StreamReader(memoryStream))
                        {
                            string xaml = streamReader.ReadToEnd();
                            xaml = xaml.Replace("<InlineUIContainer> </InlineUIContainer>", "<InlineUIContainer> " + ser + " </InlineUIContainer>");
     
                            e.DataObject.SetData(DataFormats.Xaml, xaml);
                        }
                    }
                }
            }

    Existe t il un moyen de retrouver le balisage Xaml actif d'une RichTextbox ?
    Je pense que cela existe car on obtient bien la liste d'objets Inlines (cf plus haut)
    Un autre problème surgit aussi, la sérialisation détruit les Binds et les Events... mais je pense que cela peut se résoudre.

  9. #9
    Membre habitué Avatar de swif79
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2009
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juillet 2009
    Messages : 79
    Points : 169
    Points
    169
    Par défaut
    Pour récupérer l'InlineUIContainer on peut imaginer çà
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
            private InlineUIContainer GetUserControl1()
            {
                foreach (Block block in this.rtbFlow.Document.Blocks)
                {
                    Paragraph p = block as Paragraph;
                    if (p != null)
                    {
                        foreach (Inline inline in p.Inlines)
                        {
                            InlineUIContainer iuic = inline as InlineUIContainer;
                            if (iuic != null)
                                if (this.rtbFlow.Selection.Contains(iuic.ContentStart))
                                    return iuic;
                        }
                    }
                }
     
                return null;
            }
     
    private void rtbFlow_Copying(object sender, DataObjectCopyingEventArgs e)
            {
                var rtb = sender as RichTextBox;
                if (rtb != null)
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        if (_Current != null)
                        {
                            rtb.Selection.Save(memoryStream, DataFormats.Xaml, true);
                            string ser = XamlWriter.Save(GetUserControl1());
                            memoryStream.Position = 0;
     
                            using (StreamReader streamReader = new StreamReader(memoryStream))
                            {
                                string xaml = streamReader.ReadToEnd();
                                xaml = xaml.Replace("<InlineUIContainer> </InlineUIContainer>", ser);
                                e.DataObject.SetData(DataFormats.Xaml, xaml);
                            }
                        }
                    }
                }
            }
    Un autre problème surgit aussi, la sérialisation détruit les Binds et les Events... mais je pense que cela peut se résoudre.
    Ce lien pourra peut être t'aider.

  10. #10
    Nouveau membre du Club
    Inscrit en
    Octobre 2005
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Merci swif79.

    Je me permet de transformer ta fonction, cela fonctionne si on sélectionne un seul control utilisateur mais ne fonctionne plus si il y en a au moins 2 identiques.

    Pourtant en sortie le code Xaml semble correcte... avec les InlineUIContainer bien rempli et les Span de début et de fin.

    Peut être une histoire de namespace (vu qu'on met plusieurs fois le même) ?

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
     
            private List<InlineUIContainer> GetInlineUIContainers()
            {
     
                var controls = rtbFlow.Document.Blocks.OfType<Paragraph>()
                        .SelectMany(p => p.Inlines.OfType<InlineUIContainer>())
                        .Where(u => this.rtbFlow.Selection.Contains(u.ContentStart) && this.rtbFlow.Selection.Contains(u.ContentEnd)).ToList();
     
                return controls;
            }
     
            private void rtbFlow_Copying(object sender, DataObjectCopyingEventArgs e)
            {
                var rtb = sender as RichTextBox;
                if (rtb != null)
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {                       
                        List<string> serializedControls = GetInlineUIContainers().Select(u=>XamlWriter.Save(u)).ToList();
     
                        rtb.Selection.Save(memoryStream, DataFormats.Xaml, true);
                        memoryStream.Position = 0;
                        using (StreamReader streamReader = new StreamReader(memoryStream))
                        {
                            string xaml = streamReader.ReadToEnd();
     
                            Regex reg = new Regex("<InlineUIContainer> </InlineUIContainer>");
     
                            int i = 0;
                            StringBuilder sb = new StringBuilder();
                            foreach (var split in reg.Split(xaml))
                            {
                                sb.Append(split);
                                if (serializedControls.Count() > i )
                                    sb.Append(serializedControls[i]);
                                i++;
                            }
     
                            string newxaml = sb.ToString();
                            e.DataObject.SetData(DataFormats.Xaml, newxaml);
                        }
                    }
                }
            }

  11. #11
    Nouveau membre du Club
    Inscrit en
    Octobre 2005
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Bon après de nombreux essai infructueux, je laisse de coté pour le moment, merci de vos réponses a tous.

Discussions similaires

  1. Réponses: 3
    Dernier message: 14/09/2010, 12h45
  2. [RegEx] nombre d'occurences et supprimer les mots repétés dans un texte
    Par hendrix67 dans le forum Langage
    Réponses: 3
    Dernier message: 20/04/2010, 13h11
  3. détection mot clef dans un texte
    Par Royd938 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 19/04/2006, 18h12
  4. [FLASH MX] Mot cliquable dans un texte
    Par Greutzeb dans le forum Flash
    Réponses: 2
    Dernier message: 05/05/2005, 13h20

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