使用 vb.net 统计 TextBox 中出现的所有 vbCrLf

Using vb.net Count all occurrences of vbCrLf in TextBox

我有一个文本框,我正在尝试计算 vbCrLf.

的所有出现次数

计数正常,问题是每次发出 vbCrLf 我想从某个整数中减去 33。

现在写的代码只减去vbCrLf的数字,而不是数字+33。

问题是每次按下 Enter 键并发出 vbCrLf 时如何减去 33?

我已经发布了更新的代码问题得到了回答和问题已解决
我还添加了额外的代码来增强 TextBox
的管理 您将需要这些导入
进口 System.IO
进口 System.Text

Public Class frmThree
Dim path As String = "C:/Users/Me/source/repos/TestForms/TestForms/Resource/"
Dim total As Integer
Dim vbLfTotal As Integer
Dim chrPermited As Integer = 333 'chrPermited

Private Sub btnBack_Click(sender As Object, e As EventArgs) Handles btnBack.Click
    Me.Close()
    frmOne.Show()
End Sub

Private Sub tbHaveOne_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbHaveOne.TextChanged
    Dim spaceCount, letterCount, carReturn As Integer
    spaceCount = 0
    letterCount = 0
    carReturn = 0

    Dim str As String = tbHaveOne.Text
    For Each chr As Char In str
        If chr = vbLf Then
            carReturn += 1
        ElseIf Char.IsLetterOrDigit(chr) Then
            letterCount += 1
        ElseIf Char.IsWhiteSpace(chr) Then
            spaceCount += 1
        End If
    Next

    vbLfTotal = carReturn * 29

    total = chrPermited - letterCount - spaceCount - vbLfTotal

    tbHaveTwo.ForeColor = Color.Black
    tbHaveTwo.Text = total & " More Character Can Be Entered"

    While total < 10
        tbHaveTwo.Clear()
        tbHaveTwo.ForeColor = Color.Red
        tbHaveTwo.Text = "Only " & total & " More Character Can Be Entered"
        Exit While
    End While

    If total = 5 Then
        PlaySystemSound()
    End If

    If total < 1 Then
        tbHaveTwo.Clear()
        tbHaveTwo.Text = "No More Data Entry" & total
        Call ansQ()
    End If
End Sub
Sub PlaySystemSound()
    My.Computer.Audio.PlaySystemSound(
    System.Media.SystemSounds.Hand)
End Sub
Public Sub ansQ()
    Const Msg As String = "YES Save Data" + vbCrLf + vbNewLine + "NO CANCEL"
    Const Title As String = "Save or Exit"
    Const Style = vbYesNo + vbQuestion + vbDefaultButton2
    Dim result = MsgBox(Msg, Style, Title)
    If result = vbYes Then
        Call writeDATA()
    ElseIf result = vbNo Then
        'tbHaveOne.ReadOnly = True
        'tbHaveOne.Enabled = False
        tbHaveTwo.Text = "NO Was Selected"
        'result = 0
    End If
    End Sub

Public Shared Sub tbHaveOne_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tbHaveOne.KeyDown
    'NOTE this Sub is Shared It seems to run all the time like a listener
    If e.KeyCode = Keys.Enter And frmThree.total < 40 Then
        e.SuppressKeyPress = True
    End If
End Sub

您无法检查当前字符是否为vbcrlf,因为CRLF 是两个字符。只需检查 LF,这样,如果您曾经在 unix 系统准备的文件上使用逻辑,它仍然有效(unix 有 LF,Windows 有 CRLF)

Private Sub tbHaveOne_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbHaveOne.TextChanged
    Dim spaceCount = 0
    Dim letterCount = 0
    Dim lineCount = 0

    For Each c As Char In tbHaveOne.Text
        If c = vbLf Then
            lineCount += 1
        ElseIf Char.IsLetterOrDigit(c) Then
            letterCount += 1
        ElseIf Char.IsWhiteSpace(c) Then
            spaceCount += 1
        End If
    Next c

    someInteger -= (lineCount * 33)

System.Char 具有检查字符是否在特定 Unicode 范围内的静态方法 - 对于您的字母计数,您正在计算任何不是 space 的字符,包括回车符 returns,标点符号和其他不是字母的东西,作为字母。如果你愿意,你可以继续这样做,但如果你对换行符进行三次计数,可能会导致一些混乱的计数

The counting is working the issue is every time a vbCrLf is issued I would like to subtract 33 from some Integer The code as written now only subtracts the number of vbCrLf NOT the number + 33

我不太明白。你说你想在每次换行时减去 33,这就是我所做的。第二句读起来好像要求是从 someInteger 中减去(新行数 + 33)。如果这是您想要执行的操作,请将最后一行的 * 更改为 +

Question is how to subtract 33 every time the Enter Key is pressed and a vbCrLf is issued ?

这与"count all occurrences of"完全不同;这与计算文本框中的行数无关,并且您无法通过此类代码来完成。计算用户在文本框中按下 enter 的次数需要一个钩子,该事件是在文本框具有焦点时用户按下某个键时引发的事件。为 KeyPress 或 KeyDown 事件添加处理程序:

Private Sub tbHaveOne_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles tbHaveOne.KeyPress 'KeyEventArgs for KeyDown event

    If e.KeyChar = vbCr Then 'use e.KeyCode = Keys.Enter in KeyDown event
        someInteger -= 33
    End If
End Sub

TextBox.Lines.Count returns 换行符分隔的行数(ControlChars.NewLineEnvironment.NewLine 当您按下 Enter 键时。)而不是多行 TextBox 中换行的行数。如果设置WordWrap property to False you will see the difference. See the TextBoxBase.Lines备注部分。

如果您需要获取行数,无论它们是自动换行还是分隔换行,您可以调用 SendMessage 方法和 EM_GETLINECOUNT 消息:

Imports System.Runtime.InteropServices

Private Const EM_GETLINECOUNT As UInteger = &HBA

<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr,
                                ByVal msg As Integer,
                                ByVal wp As IntPtr,
                                ByVal lp As IntPtr) As IntPtr
End Function

Private Sub PrintCounts()
    Dim c = tbHaveOne.Text.
        Aggregate(New With {
        .WhiteSpaces = 0, .Lf = 0, .NewLines = 0, .Lines = 0, .Others = 0
                    },
                    Function(x, y)
                        x.Lf += If(y = ControlChars.Cr, 1, 0)
                        x.WhiteSpaces += If(Char.IsSeparator(y), 1, 0)
                        x.Others += If(Not Char.IsWhiteSpace(y), 1, 0)
                        Return x
                    End Function)

    c.NewLines = tbHaveOne.Lines.Count
    c.Lines = SendMessage(tbHaveOne.Handle, EM_GETLINECOUNT, 
                          IntPtr.Zero, IntPtr.Zero).ToInt32

    tbHaveTwo.Text = $"WhiteSpaces: {c.WhiteSpaces} Lf: {c.Lf} " +
                        $"New Lines: {c.NewLines} Lines {c.Lines} Others: {c.Others}"

End Sub

Private Sub tbHaveOne_TextChanged(sender As Object, 
                                  e As EventArgs) Handles tbHaveOne.TextChanged
    PrintCounts()
End Sub

请注意:

  • Char.IsSeparator方法用于获取空格的计数,因为Char.IsWhiteSpace方法在求值时会returnTruevbCrvbLfvbCrLfvbTab、...等等。或者,您可以结合使用 Char.IsWhiteSpaceChar.IsControl 方法来计算空格。 Remarks 部分有更多内容。

  • Others 是其他所有内容的计数,包括字母、数字、标点符号、符号...等。您可能不会检查 Char 结构的其他 Char.IsXXX 方法。

  • 在键入时检查 LinesNewLines 字段的值。

我们对这个问题有很多很好的讨论和固定答案
讨论中的一个问题是如何处理标点符号和特殊字符
我们想提供此代码作为管理标点符号和特殊字符的方法

    Dim spaceCount, letterCount, carReturn, punCount, syCount As Integer
    spaceCount = 0
    letterCount = 0
    carReturn = 0
    punCount = 0
    syCount = 0
    Dim str As String = tbHaveOne.Text
    For Each chr As Char In str
        If chr = vbLf Then
            carReturn += 1
        ElseIf Char.IsLetterOrDigit(chr) Then
            letterCount += 1
        ElseIf Char.IsWhiteSpace(chr) Then
            spaceCount += 1
        ElseIf Char.IsPunctuation(chr) Then
            punCount += 1
        ElseIf Char.IsSymbol(chr) Then
            syCount += 1
        End If
    Next

    vbLfTotal = carReturn * 29
    total = chrPermited - letterCount - spaceCount - vbLfTotal - punCount - syCount
    tbHaveTwo.ForeColor = Color.Black
    tbHaveTwo.Text = total & " More Character Can Be Entered"