【问题标题】:dynamically change text decorations on multiple spans/regions in a wpf textblock动态更改 wpf 文本块中多个跨度/区域上的文本装饰
【发布时间】:2015-09-14 22:50:25
【问题描述】:

我正在尝试设计一个应用程序,如果该字符串中包含另外 1 或 2 个字符串,则该应用程序会删除该字符串上的某些字符。

到目前为止,我似乎可以让前导子字符串相当可靠地完成它的工作,但是第二个子字符串似乎总是产生不可预测的结果,有人可以帮忙吗? (c#或vb都可以)

一个屏幕截图示例,它适用于主(第一个)过滤器,但不适用于子(第二个):

代码如下:

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

【问题讨论】:

  • 哈,老乔博客。

标签: c# .net wpf vb.net textblock


【解决方案1】:

如果您在 tbNew.ContentEnd.Offset 上设置监视来运行代码,您会看到应用删除线时值发生变化。这说明了为什么使用

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

不准确 - 您从纯文本中获取 IndexOf,然后将该偏移量应用于应用了文本装饰的内容。

here 的回答来看,这应该可以让您顺利上路。

  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

【讨论】:

  • 谢谢这成功了!认为纯文本可能会导致不可预测性,但在获取富文本索引的实现中错过了几点。感谢您的帮助:)
  • 不用担心 - 自从我使用 WPF 以来已经有很长一段时间了,但在 Google 和 SO 的帮助下拼凑了我能记住的东西 :)
  • 请记住,如果您的过滤器字符串也多次出现,这将无法处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
  • 1970-01-01
  • 2011-07-26
  • 2014-09-19
相关资源
最近更新 更多