Sub txtprice_TextChanged (Old As String, New As String)
If IsNumber(txtprice.Text.Replace(",","")) Then
txtprice.Text = NumberToCurrency(txtprice.Text.Replace(",",""))
End If
End Sub
It crash suddenlyAnd the error that you are getting?
Check the device log, there should be something there to indicate the nature of the crash (e.g. Stack Overflow, or Division by Zero, etc.).It crash suddenly
Because when i change text,again TextChaned event raised and loop
This functionWhat does NumberToCurrency do?
Sub ConvertNumber2Currency(MyNumber As Double) As String
Dim AHL As AHLocale 'need the AHlocale library
Dim res As String
AHL.InitializeUS
Dim MyFrac As Int =AHL.CurrencyFractionDigits
res = NumberFormat2(MyNumber,1,MyFrac,MyFrac,True)
Return res.SubString2(0,res.LastIndexOf("."))
End Sub
If MyGlobalBoolean = False then
MyGlobalBoolean = True
If IsNumber(txtprice.Text.Replace(",","")) Then
txtprice.Text = NumberToCurrency(txtprice.Text.Replace(",",""))
End If
MyGlobalBoolean = False
End If
For these kind of situations, local static variables would be very useful; so, I will open a "wish" thread.I would set a global variable to indicate we're adjusting the contents then check that variable in the event
The TextChanged event will fire whenever the text changes.Setting the .Text property of the control appears to be recurisively calling the _TextChanged event
Yes it is bad experience.The TextChanged event will fire whenever the text changes.
The problem in this code is that it modifies the text even when it is formatted properly. As a general rule, modifying the text in the TextChanged event leads to bad user experience. You should instead change it after the focus shifts to a different view or when the user clicks on the action button.
Yes it is good solutionSetting the .Text property of the control appears to be recurisively calling the _TextChanged event, resulting in a stack overflow.
I would set a global variable to indicate we're adjusting the contents then check that variable in the event, something like:
B4X:If MyGlobalBoolean = False then MyGlobalBoolean = True If IsNumber(txtprice.Text.Replace(",","")) Then txtprice.Text = NumberToCurrency(txtprice.Text.Replace(",","")) End If MyGlobalBoolean = False End If
Sub edAmount_TextChanged (Old As String, New As String)
Dim pattern As String
pattern = "[0-9]+(\.[0-9][0-9])" 'any number of digits, optionally followed by a dot and up to 2 digits
Dim Matcher1 As Matcher
Matcher1 = Regex.Matcher(pattern, New)
If Not(Matcher1.Find) Then New = Old
End Sub
Sub edAmount_TextChanged (Old As String, New As String)
If Old = New Then Return
Dim pattern As String
pattern = "(\d+\.\d{1,2})" 'a few digits followed by a dot and 1 or 2 digits more
Dim Matcher1 As Matcher
Matcher1 = Regex.Matcher(pattern, New)
If Not(Matcher1.Find) Then
New = Old
Return
Else
New = Matcher1.Group(0)
Old = New
edAmount.Text = New
edAmount.SelectionStart =edImporto.Text.Length
End If
End Sub
The TextChanged event will fire whenever the text changes.
The problem in this code is that it modifies the text even when it is formatted properly. As a general rule, modifying the text in the TextChanged event leads to bad user experience. You should instead change it after the focus shifts to a different view or when the user clicks on the action button.
B4A (and even Android) is not Visual Basic for Windows.I have used that method under Visual Basic for Windows for a long time.
As I see it the main issue with modifying the text in TextChanged is not the recursive loop. This can be solved by making sure that the code doesn't change the programmatically set text (which should already be formatted). The problem is that it can be annoying to the user:
1. The cursor will jump to a different location when the new text is set.
2. It is expected that the text will not always be valid. It should only be valid once the user completed writing it. So trying to format the intermediate text just makes it more difficult for the user to correct it.
There are cases where it is valid, for example if you want to limit the text length.