使用vb.net 对TextBox中出现的所有vbCrLf进行计数。

问题描述 投票:0回答:2

我有一个TextBox,我试图计算所有出现的 vbCrLf.

计数是有效的,问题是每当一个 vbCrLf 我想从某个Integer中减去33。

现在写的代码只减去了这个数字的 vbCrLf,而不是数字+33.问题是如何在每次按下回车键和发出vbCrLf时减去33?

问题是如何在每次按回车键和发出vbCrLf时减去33?

我已经发布了更新的代码,问题得到了解答,并发布了问题 已解决 我还添加了额外的代码,以增强对TextBox的管理 你将需要这些 Imports Imports System.IO Imports 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
vb.net textbox counter
2个回答
1
投票

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

    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"

2
投票

TextBox.Lines.Count 返回由换行符分隔的行数 (ControlChars.NewLine环境.NewLine 当你打 进入 键),而不是多行TextBox中的包字行数。如果您在多行TextBox中设置了 WordWrap 属性为 False 你会看到区别。请看 TextBoxBase.Lines 备注部分。

您可以调用 发送消息 方法和 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 方法将返回 True 评价时。vbCr, vbLf, vbCrLf, vbTab,...等等。或者,你也可以将 Char.IsWhiteSpaceChar.IsControl 的方法来评估白色空间。该 备注 节有更多。

  • Others 是其他一切的计数,包括字母、数字、标点、符号......等等。你可能会想检查其他的 Char.IsXXX 的方法 Char 结构。

  • 检查一下 LinesNewLines 字段。


2
投票

你不能检查当前字符是否是vbrlf,因为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范围内--对于你的字母计数,你把任何不是空格的东西都算作字母,包括回车、标点符号和其他不是字母的东西。如果你愿意,你可以继续这样做,但是如果你把换行符的数量增加了三倍,可能会导致计数混乱。

问题是每次发出vbCrLf时,我想从某个Integer中减去33,现在写的代码只减去vbCrLf的数量,而不是+33。

我不太明白这个。你说每次有新行时要减去33,我就是这么做的。第二句话读起来像是要求从someInteger中减去(新行数+33)。如果你想这样做,把最后一行的*改成+。

问题是如何在每次按下回车键和发出vbCrLf时减去33 ?

这与 "计算所有出现的次数 "完全是两码事,它与计算文本框中的行数无关,而且你也无法从这样的代码中实现。计算用户在文本框中按下回车键的次数需要一个钩子,钩到当用户在文本框有焦点时按下一个键时引发的事件。为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
© www.soinside.com 2019 - 2024. All rights reserved.