2015-09-14 3 views
0

J'essaie de concevoir une application qui détruit certains caractères d'une chaîne si 1 ou 2 autres chaînes sont contenues dans cette chaîne. Jusqu'à présent, j'ai l'impression que la sous-chaîne principale est assez fiable, mais la deuxième sous-chaîne semble toujours produire des résultats imprévisibles. Quelqu'un peut-il m'aider? (C# ou vb est très bien)modifier dynamiquement les décorations de texte sur plusieurs travées/régions dans un bloc de texte wpf

Un écran snip exemple de faire fonctionner le filtre principal (1er), mais pas le sous (2): enter image description here

Heres le code:

Public Function FormatFilteredName(mainFilter As String, subFilter As String) As TextBlock 
    Dim tbNew As New TextBlock(New Run(FullFileName)) 
    tbNew.Text = FullFileName 
    tbNew.FontSize = FONT_SIZE 
    If Not String.IsNullOrEmpty(FullFileName) Then 
     If Not String.IsNullOrEmpty(mainFilter) Then 
      GetFilterSpan(mainFilter, tbNew) 
     End If 
     If Not String.IsNullOrEmpty(subFilter) Then 
      GetFilterSpan(subFilter, tbNew) 
     End If 
    End If 
    Return tbNew 

Private Function GetFilterSpan(filter As String, ByVal tbNew As TextBlock) As Span 
    Dim offset As Integer = tbNew.Text.ToLower().IndexOf(filter.ToLower()) + 1 
    Try 
     If offset > -1 Then 
      Dim tpStart As TextPointer 
      tpStart = tbNew.ContentStart.GetPositionAtOffset(offset) 
      Dim tpEnd As TextPointer 
      tpEnd = tbNew.ContentStart.GetPositionAtOffset(offset + filter.Length) 
      If Not tpStart Is Nothing And Not tpEnd Is Nothing Then 
       Dim result As New Span(tpStart, tpEnd) 
       result = ApplySpanStrikeOutStyle(result) 
       Return result 
      End If 
     End If 
    Catch ex As Exception 
     Return Nothing 
    End Try 
+0

Hah, les bons vieux Joe Blogs. – Mathemats

Répondre

1

Si vous exécutez votre code avec un jeu de surveillance sur tbNew.ContentEnd.Offset, vous verrez la valeur changer à mesure que les barrés sont appliqués. Cela illustre pourquoi l'utilisation

Dim offset As Integer = tbNew.Text.ToLower().IndexOf(filter.ToLower()) + 1

est pas précis - vous obtenez le IndexOf du texte brut, puis l'application de ce décalage au contenu qui a des décorations de texte appliquées.

De la réponse here, cela devrait vous mettre en route.

Public Function FormatFilteredName(mainFilter As String, subFilter As String) As TextBlock 
     ' Dim tbNew As New TextBlock(New Run("111xxJoe Blogs09")) 
     ' tbNew.Text = "111xxJoe Blogs09" 
     ' tbNew.FontSize = 10 
     If Not String.IsNullOrEmpty(tbNew.Text) Then 
      If Not String.IsNullOrEmpty(mainFilter) Then 
       Dim mainFilterRange As TextRange = FindWordFromPosition(tbNew.ContentStart, mainFilter) 
       If mainFilterRange IsNot Nothing Then 
        ApplyStrikeOutStyle(mainFilterRange) 
       End If 
      End If 
      If Not String.IsNullOrEmpty(subFilter) Then 
       Dim subFilterRange As TextRange = FindWordFromPosition(tbNew.ContentStart, subFilter) 
       If subFilterRange IsNot Nothing Then 
        ApplyStrikeOutStyle(subFilterRange) 
       End If 
      End If 
     End If 
     Return tbNew 
    End Function 



    Private Function ApplyStrikeOutStyle(result As TextRange) As TextRange 
     result.ApplyPropertyValue(Inline.TextDecorationsProperty, 
          TextDecorations.Strikethrough) 
     Return result 
    End Function 


    Private Function FindWordFromPosition(position As TextPointer, word As String) As TextRange 
     While position IsNot Nothing 
      If position.GetPointerContext(LogicalDirection.Forward) = TextPointerContext.Text Then 
       Dim textRun As String = position.GetTextInRun(LogicalDirection.Forward) 

       ' Find the starting index of any substring that matches "word". 
       Dim indexInRun As Integer = textRun.IndexOf(word) 
       If indexInRun >= 0 Then 
        Dim start As TextPointer = position.GetPositionAtOffset(indexInRun) 
        Dim [end] As TextPointer = start.GetPositionAtOffset(word.Length) 
        Return New TextRange(start, [end]) 
       End If 
      End If 

      position = position.GetNextContextPosition(LogicalDirection.Forward) 
     End While 

     ' position will be null if "word" is not found. 
     Return Nothing 
    End Function 
+0

Merci cela fait l'affaire! Pensé que le texte brut était susceptible de provoquer l'imprévisibilité, mais a manqué quelques points dans la mise en œuvre de l'obtention de l'index de texte enrichi. Appréciez votre aide :) – MikeDub

+0

Pas de soucis - il y a longtemps que je travaillais avec WPF, mais j'ai réuni ce dont je me souvenais avec l'aide de Google et SO :) – Donnelle

+0

Rappelez-vous que cela ne gérera pas s'il y a plusieurs occurrences de vos chaînes de filtre , aussi. – Donnelle