【问题标题】:get paragraph number (not line number) of paragraph in richtextbox vb.net获取richtextbox vb.net中段落的段落号(不是行号)
【发布时间】:2020-08-30 00:27:07
【问题描述】:

我有一个包含大量段落的富文本框。 (仅供参考:所有段落将由 vbCrlf 分隔)

我需要知道光标位置的段落索引。

很容易找到行索引

    Dim line, index As Integer
    index = rtbScriptRTF.SelectionStart
    line = rtbScriptRTF.GetLineFromCharIndex(index)
    txtTestLINE.Text = line

这不是我想要的,因为一个段落很容易占据很多行。

疯狂的是......我在这些页面的某个地方看到了一段代码,它就是这样做的,但我在任何地方都找不到它!

谁能指出我正确的方向或者帮助我正确的语法? 谢谢!

编辑:我已添加使用的代码,但现在无法使用键盘箭头导航文本 - 是否有解决方法?

Private Sub rtbScriptRTF_KeyDown(sender As Object, e As KeyEventArgs) Handles rtbScriptRTF.KeyDown
    Dim index As Integer
    Dim lineNum As Integer

    rtbScriptRTF.Focus()
    rtbScriptRTF.SuspendLayout()
    rtbScriptRTF.WordWrap = False


    Index = rtbScriptRTF.SelectionStart
    lineNum = rtbScriptRTF.GetLineFromCharIndex(index)
    txtTestLINE.Text = lineNum + 1

    rtbScriptRTF.WordWrap = True
    rtbScriptRTF.ResumeLayout()
End Sub

【问题讨论】:

  • 段落的定义是什么?一条新线?多行新行(如果有的话)?
  • 在 vbcrlf 之前的所有文本将是一个段落,在 vbcrlf 之后将开始另一个段落。因此,一个段落中可能有相当多的行。抱歉,我似乎没有说清楚。 -- 更新了我的问题以反映这一点。
  • 不幸的是,您可能必须设置 richTextBox1.WordWrap = false 然后设置 dim lineNum = richTextBox1.GetLineFromCharIndex(index) 并返回 richTextBox1.WordWrap = true 或获取所有 \n (VbLf, char 10) 字符的位置,直到你有一个值> index 或进入正文。
  • 如果选择前一种方法,设置[RichTextBox].SuspendLayout(),然后改变WordWrap属性,获取行索引,然后[RichTextBox].ResumeLayout(),否则控件会明显闪烁。
  • 如果您真的想在按键事件中使用该代码,请使用 KeyUp 事件,而不是 KeyDown。删除rtbScriptRTF.Focus() 并更改:txtTestLINE.Text = (lineNum + 1).ToString()(表明您有 Option Strict Off,非常糟糕)。您不应该在按键事件中使用这种代码。尝试寻找其他用途。

标签: vb.net richtextbox paragraph


【解决方案1】:

WinForm RichTextBox 包装的原生 RichEdit 控件支持Text Object Model 的子集。

TOM 定义了大量的文本操作接口。 Microsoft Word 和富编辑控件等文本解决方案支持 TOM 功能集。

添加对“tom”的项目 COM 引用以访问 .Net 项目中的接口定义。然后,您通过将 EM_GETOLEINTERFACE message 发送到控件来获得对 TOM ITextDocument interface 的引用。获得文档参考后,您可以像使用 MS Word 的对象模型一样导航文档。

在下面的示例中(创建一个带有RichTextBox 和标签的新WinForm 项目),SelectionChanged 事件用于在标签中显示所选段落的编号。请注意,作为此 COM,编号从索引一 (1) 而不是零 (0) 开始。文档引用(存储在变量“doc”中)是在创建 RichTextBox 句柄时获取的。

' add project COM reference to "tom" 

Imports System.Runtime.InteropServices

Public Class Form1
  Private doc As tom.ITextDocument
  Private comCallCount As Int32 = 1 ' used to force GC to cleanup unreferenced COM object

  Public Sub New()
    InitializeComponent()
    PopulateRTB()
  End Sub

  Private Sub PopulateRTB()
    With RichTextBox1
      .AppendText("Paragraph 1: Lorem ipsum dolor sit amet, solum lobortis pri id, vocent volumus praesent nam ut. Impetus aliquip quo at. Eos nisl veniam fierent an, cu dictas veritus vivendo mea, ei sea eruditi prodesset percipitur. Duo in case eirmod adipiscing, qui habemus scriptorem id. Mei nihil facilisis cu, id sumo laboramus consectetuer vel. No nostrud aliquid quo. Nam doming melius scripta eu." & Environment.NewLine)
      .AppendText(Environment.NewLine)
      .AppendText("Paragraph 3: An pri consul adversarium, ea mel semper quaeque complectitur. Mea te solet concludaturque, ei mucius albucius sit. Per no lucilius detraxit adipisci, ut tamquam delenit cotidieque cum. Mea putent apeirian sapientem cu. Per saperet accumsan rationibus at." & Environment.NewLine)
      .AppendText(Environment.NewLine)
      .AppendText("Paragraph 5: Velit tollit voluptua pri ut. Convenire honestatis no nam, nulla legere salutatus at ius. Ea duo nisl everti aliquid, dolore aperiam tractatos te duo, quaeque veritus ad vim. At vim consul laoreet, inermis iudicabit et vim." & Environment.NewLine)
      .AppendText(Environment.NewLine)
      .AppendText("Paragraph 7: Altera efficiendi ad qui, ne quo viris moderatius. Idque singulis suavitate ea vix, vis at ancillae detraxit contentiones, has constituam sadipscing et. Eos et iudico corrumpit, augue nominavi ad mel. Impetus equidem eu duo. Ea sale legimus dignissim vix." & Environment.NewLine)
      .AppendText(Environment.NewLine)
      .AppendText("Paragraph 9: Et quodsi oblique iudicabit pro, an nam augue consulatu, ad cum graece malorum mediocritatem. Vivendo ullamcorper vim et, maiestatis accommodare sit cu. Duo vocent deleniti et, nec ei congue melius tamquam, modo phaedrum no sea. Ius at velit augue soleat." & Environment.NewLine)
    End With
  End Sub

  Private Sub RichTextBox1_HandleCreated(sender As Object, e As EventArgs) Handles RichTextBox1.HandleCreated
    Const WM_USER As Int32 = &H400
    Const EM_GETOLEINTERFACE As Int32 = WM_USER + 60
    If doc IsNot Nothing Then
      Marshal.FinalReleaseComObject(doc)
      doc = Nothing
    End If
    SendMessage(New HandleRef(Me, RichTextBox1.Handle), EM_GETOLEINTERFACE, IntPtr.Zero, doc)
  End Sub

  Private Sub RichTextBox1_HandleDestroyed(sender As Object, e As EventArgs) Handles RichTextBox1.HandleDestroyed
    If doc IsNot Nothing Then
      Marshal.FinalReleaseComObject(doc)
      doc = Nothing
    End If
  End Sub

  Private Sub RichTextBox1_SelectionChanged(sender As Object, e As EventArgs) Handles RichTextBox1.SelectionChanged
    Label1.Text = $"In paragraph number: {doc.Selection.GetIndex(tom.tomConstants.tomParagraph)}"
    comCallCount += 1
    If comCallCount = 10 Then
      CleanupUnreferencedCOM()
      comCallCount = 1
    End If
  End Sub

  Private Sub CleanupUnreferencedCOM()
    Do
      GC.Collect()
      GC.WaitForPendingFinalizers()
    Loop While Marshal.AreComObjectsAvailableForCleanup
  End Sub

  <DllImport("user32.dll", CharSet:=CharSet.Auto)>
  Public Shared Function SendMessage(ByVal hWnd As HandleRef, ByVal msg As Integer, ByVal wParam As IntPtr, ByRef lParam As tom.ITextDocument) As IntPtr
  End Function

End Class

Bradley Smith 还提供了 Managed Wrapper for the Text Object Model (TOM) 库,它使使用对象模型变得更容易一些。如果您选择使用此库,请注意作者通过托管代码添加了功能,并且库中同时存在基于零和一的索引。因此,请务必阅读 Intellisense 文档或主要项目文档以避免意外。

【讨论】:

    猜你喜欢
    • 2020-04-29
    • 2011-07-15
    • 1970-01-01
    • 2021-09-23
    • 2012-02-11
    • 1970-01-01
    • 2021-11-25
    • 2021-08-28
    • 1970-01-01
    相关资源
    最近更新 更多