我有一个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
我们有很多关于这个问题的精彩讨论和固定答案 讨论中的一个问题是如何处理标点符号和特殊字符 我们想提供这段代码作为管理标点符号和特殊字符的方法
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"
该 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
请注意:
你不能检查当前字符是否是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