2012-04-24 1 views
1

J'essaie de créer un contrôle utilisateur à l'aide de la Silverlight 5 richtextbox. Je dois être capable d'insérer "inline ui" et ne peux pas trouver comment obtenir la position actuelle du curseur.Silverlight Richtextbox obtenir la position du curseur

je déclenche mon code comme ceci:

this.GetAbsolutePos(this.richText.Selection.Start); 

Les entrailles de cette méthode est ici:

private int GetAbsolutePos(TextPointer textPointer) 
{ 
    int index = 0; 
    TextPointer pos = this.richText.ContentStart; 
    while (pos.CompareTo(textPointer) != 0) 
    { 
     if (pos.IsAtInsertionPosition) 
     { 
      index++; 
     } 

     pos = pos.GetNextInsertionPosition(LogicalDirection.Forward); 
    } 
    return index; 
} 

Compte tenu du texte suivant dans un contrôle RichTextBox ....

Empty Control

Si le curseur est entre 5 & 6 sur la première ligne, alors la fonction ci-dessus renvoie correctement 5. Mais comme le curseur est plus loin dans le texte, la position devient plus inexacte. Par exemple, entre 5 & 6 sur la deuxième ligne renvoie 16 et la troisième ligne renvoie 27.

Il devient également plus difficile que j'insère des éléments en ligne à ces positions, qui comptent alors comme un «symbole» et causent en outre la compte pour aller mal.

Cette image montre ce qui se passe lorsque je "insère" l'interface utilisateur en ligne entre 5 & 6 sur chaque ligne. With 3 Inlines

Juste pour être complet ici est le Xaml de richtext.Xaml (je l'ai enlevé tous les attributs supplémentaires des éléments Section/Paragraphe pour le rendre plus clair)

<Section> 
    <Paragraph> 
     <Run>1234567890</Run> 
     <LineBreak /> 
     <Run>1234567890</Run> 
     <LineBreak /> 
     <Run>1234567890</Run> 
    </Paragraph> 
</Section> 

Sur la base des remarques sur ce Page MSDN Silverlight TextPointer Class

Symbole - pour les opérations TextPointer, l'un des suivants est considéré comme un symbole:

  • Une balise d'ouverture ou de fermeture pour un élément TextElement.

  • Un élément UIElement contenu dans un InlineUIContainer. Notez que un UIElement est toujours compté comme exactement un symbole. Tout contenu additionnel ou les éléments contenus dans l'UIElement ne sont pas considérés comme des symboles .

  • Chaque caractère Unicode de 16 bits à l'intérieur d'un élément d'exécution de texte.

Je pense que je dois « savoir » quel genre de « symbole » Je suis actuellement mais ne peut pas comprendre comment.

On dirait que cela devrait être facile, mais travailler avec TextPointers semble très peu intuitif. J'ai eu une idée pour analyser le Xaml pour trouver la position du curseur, mais cela ressemble à un vrai hack.

Toute aide serait appréciée.

Merci

+0

Avez-vous trouvé une bonne solution pour cela? –

+0

Ajouté une réponse pour vous. –

Répondre

0

En fin de compte, nous ajustons simplement juste manuellement l'index par le nombre de SubstituteEdits (notre représentation du UIElement) qui sont avant le point de texte. C'est encore floconneux et nous avons d'autres problèmes avec notre contrôle, mais c'est assez bon pour le moment.

Vive

Tim

private int GetAbsolutePos(SubstituteEdit newSub) 
    { 
     int index = 0; 
     TextPointer textPointer = this.richText.Selection.Start; 
     TextPointer caretWhere = this.richText.ContentStart; 

     while (true) 
     { 
      caretWhere = caretWhere.GetNextInsertionPosition(LogicalDirection.Forward); 
      if (caretWhere == null || caretWhere.CompareTo(textPointer) == 0) 
      { 
       break; 
      } 

      index++; 
     } 

     foreach (SubstituteEdit sub in this.Substitutes) 
     { 
      if (sub.Position < index && sub != newSub) 
      { 
       index--; 
      } 
     } 

     return index; 
    } 
0

Je ne sais pas si cela va aider, mais je fini par laisser l'insertion d'utilisateur où la sélection est au lieu de la position de caret et il semble bien fonctionner. Voici une partie de mon code:

InlineUIContainer MyUI = new InlineUIContainer(); 
TextBlock tblx = new TextBlock() { Text = addedItem.Title, FontWeight = FontWeights.Bold }; 
MyUI.Child = tblx; 
Paragraph myParagraph = new Paragraph(); 
myParagraph.Inlines.Add(MyUI); 
rtb.Selection.Insert(myParagraph); 
Questions connexes