I was wondering if there is a way to allow only some sections of a textbox to be editable in a frozen sentence.
e.g:
He share of ________ to worse. Weddings and any opinions suitable smallest nay.
My he houses or months settle remove ladies appear. Engrossed suffering
supposing he recommend do eagerness.
where the underscore can be edited but the sentences cannot be changed at all.
Thanks
A simple solution for your example
Public Class Form1
Private SelectionStart As Integer = 10
Private SelectionEnd As Integer = 20
Private SelectionCurrent As Integer = 10
Private Sub CursorControl(Optional ByVal e As Object = Nothing)
If SelectionCurrent > SelectionEnd Then
SelectionCurrent = SelectionEnd
ElseIf SelectionCurrent < SelectionStart Then
SelectionCurrent = SelectionStart
End If
If TextBox1.SelectionStart >= SelectionEnd Then
If Not e Is Nothing Then
e.Handled = True
e = Nothing
End If
TextBox1.SelectionStart = SelectionEnd
TextBox1.SelectionLength = 0
Me.SelectionCurrent = TextBox1.SelectionStart
ElseIf TextBox1.SelectionStart <= SelectionStart Then
If Not e Is Nothing Then
e.Handled = True
e = Nothing
End If
TextBox1.SelectionStart = SelectionStart
TextBox1.SelectionLength = 0
Me.SelectionCurrent = TextBox1.SelectionStart
Else
Me.SelectionCurrent = TextBox1.SelectionStart
End If
End Sub
Private Sub TextBox1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Click
CursorControl()
End Sub
Private Sub TextBox1_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.GotFocus
CursorControl()
End Sub
Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
TextBox1.SelectionStart = Me.SelectionCurrent
TextBox1.SelectionLength = 0
If e.KeyCode = Keys.Right Or e.KeyCode = Keys.Left Or e.KeyCode = Keys.Down Or e.KeyCode = Keys.Up Then
e.Handled = True
e = Nothing
End If
CursorControl(e)
End Sub
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
TextBox1.SelectionStart = Me.SelectionCurrent
TextBox1.SelectionLength = 0
If e.KeyChar = "_" Then
e.Handled = True
End If
If TextBox1.SelectionStart >= SelectionEnd Then
e.Handled = True
e = Nothing
ElseIf TextBox1.SelectionStart <= SelectionStart Then
e.Handled = True
e = Nothing
Else
TextBox1.Text = TextBox1.Text.Substring(0, TextBox1.SelectionStart) & e.KeyChar & TextBox1.Text.Substring(TextBox1.SelectionStart + 1, TextBox1.Text.Length - TextBox1.SelectionStart - 1)
TextBox1.SelectionStart = Me.SelectionCurrent
e.Handled = True
e = Nothing
End If
CursorControl()
End Sub
Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp
TextBox1.SelectionStart = Me.SelectionCurrent
TextBox1.SelectionLength = 0
If e.KeyCode = 189 Then '_
e.Handled = True
End If
Me.SelectionCurrent = Me.SelectionCurrent + 1
Me.TextBox1.SelectionStart = Me.SelectionCurrent
CursorControl(e)
End Sub
End Class
Put three TextBoxes next to each other and allow only the middle one to be edited. Here's some XAML:
<StackPanel
Orientation="Horizontal">
<TextBox
Text="He share of"
IsReadOnly=True />
<TextBox
Text="<Enter your phrase here>" />
<TextBox
Text="to worse. ......."
IsReadOnly=True />
</StackPanel>
The end user will see the whole line as one unit.
The Winform control RichTextBox via the SelectionProtected Property allows you to mark text ranges a readonly (protected).
Marking the entire text as protected and then selectively unprotecting the desired editable range will produce the desired effect.
Public Class Form1
Private underlinedFont As Font
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
RichTextBox1.Text = "This is protected. This is unprotected."
' Protect all text
RichTextBox1.SelectAll()
RichTextBox1.SelectionProtected = True
' Unprotect the word "unprotected"
Dim startUnProtected As Int32 = RichTextBox1.Find("unprotected", RichTextBoxFinds.WholeWord)
If startUnProtected > -1 Then
RichTextBox1.SelectionProtected = False
If underlinedFont Is Nothing Then underlinedFont = New Font(RichTextBox1.Font.FontFamily, RichTextBox1.Font.Size, FontStyle.Underline, RichTextBox1.Font.Unit)
RichTextBox1.SelectionFont = underlinedFont
End If
End Sub
End Class
Related
I managed to make my app capture any key to use it as a hotkey, but when I press the key the hotkey function is activated. This is what I have so far:
Private Sub tmrFunc_Tick(sender As Object, e As EventArgs) Handles tmrFunc.Tick
'Function
End Sub
Private Sub tmrKey_Tick(sender As Object, e As EventArgs) Handles tmrKey.Tick
'Uses the hotkey to start and stop tmrF
End Sub
Private Sub lblCapKey_Click(sender As Object, e As EventArgs) Handles lblCapKey.Click
tmrKey.Enabled = False
txtbStartFunc.Enabled = True
txtbStartFunc.Text = "Press any key"
txtbStartFunc.Focus()
End Sub
Private Sub txtbStartFunc_KeyDown(sender As Object, e As KeyEventArgs) Handles txtbStartFunc.KeyDown
If e.KeyCode = Keys.F10 Then
txtbStartFunc.Text = "F10"
End If
tmrKey.Enabled = True
txtbStartFunc.Enabled = False
End Sub
The current code perfectly captures the key and uses it as a hotkey, the problem is that the hotkey is activated on this first key pressed and that causes it to be activated unexpectedly at the wrong time.
My current goal is that the function is not activated with the first keystroke, but is activated with the following keystrokes.
I am expecting something like this:
Private Sub txtbStartFunc_KeyDown(sender As Object, e As KeyEventArgs) Handles txtbStartFunc.KeyDown
If e.KeyCode = Keys.F10 Then
txtbStartFunc.Text = "F10"
End If
tmrKey.Enabled = True
'=========================
tmrFunc.Enabled = False
'=========================
txtbStartFunc.Enabled = False
End Sub
Here's a solution that finally worked for me. It allows you to set the hotkeys between F1 and F10, but won't let you select the same key for both of them.
This is pretty different than what you had, so take your time studying it and ask as many questions as need be:
Public Class Form1
Private Const KeyDownBit As Integer = &H8000
Private Enum HotKeyType
StartClicker
StopClicker
End Enum
Private _StartHotkey As Keys
Private _StopHotKey As Keys
Private SelectingHotKey As HotKeyType
Private HotKeySelected As Boolean = False
Private _SettingHotKey As Boolean = False
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKeys As Integer) As Short
Private Property StartHotKey As Keys
Get
Return _StartHotkey
End Get
Set(value As Keys)
If value <> StopHotKey Then
_StartHotkey = value
TextBox1.Text = StartHotKey.ToString
End If
End Set
End Property
Private Property StopHotKey As Keys
Get
Return _StopHotKey
End Get
Set(value As Keys)
If value <> StartHotKey Then
_StopHotKey = value
TextBox2.Text = StopHotKey.ToString
End If
End Set
End Property
Private Property SettingHotKey As Boolean
Get
Return _SettingHotKey
End Get
Set(value As Boolean)
If value Then
HotKeySelected = False
Timer2.Stop()
Else
Timer2.Start()
End If
_SettingHotKey = value
End Set
End Property
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.KeyPreview = True
Timer1.Enabled = False
Timer2.Enabled = False
Timer1.Interval = 50
Timer2.Interval = 50
TextBox1.ReadOnly = True ' they just stay this way all the time
TextBox2.ReadOnly = True ' they just stay this way all the time
StartHotKey = Keys.F1
StopHotKey = Keys.F2
Timer2.Start()
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
Dim startKeyDown, stopKeyDown As Boolean
GetAsyncKeyState(StartHotKey) ' disregard first call to "flush it"
startKeyDown = (GetAsyncKeyState(StartHotKey) And KeyDownBit) = KeyDownBit ' see if it's down
GetAsyncKeyState(StopHotKey) ' disregard first call to "flush it"
stopKeyDown = (GetAsyncKeyState(StopHotKey) And KeyDownBit) = KeyDownBit ' see if it's down
TextBox1.BackColor = If(startKeyDown, Color.Green, Control.DefaultBackColor)
TextBox2.BackColor = If(stopKeyDown, Color.Green, Control.DefaultBackColor)
If startKeyDown Then
Timer1.Start()
End If
If stopKeyDown Then ' if you hold both down, then it'll stop
Timer1.Stop()
Label1.BackColor = Control.DefaultBackColor
End If
End Sub
Private Sub BothButtons_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
SelectingHotKey = If(sender Is Button1, HotKeyType.StartClicker, HotKeyType.StopClicker)
SettingHotKey = True ' automatically turns off Timer2
Dim tb As TextBox = If(sender Is Button1, TextBox1, TextBox2)
tb.Text = "Press F1 to F10"
End Sub
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
Select Case keyData
Case Keys.F1 To Keys.F10
If SettingHotKey Then
If SelectingHotKey = HotKeyType.StartClicker Then
If keyData <> StopHotKey Then
StartHotKey = keyData
HotKeySelected = True
Return True
End If
Else
If keyData <> StartHotKey Then
StopHotKey = keyData
HotKeySelected = True
Return True
End If
End If
End If
End Select
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If SettingHotKey AndAlso HotKeySelected Then
SettingHotKey = False ' restarts Timer2 once selected key has been released
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Label1.BackColor = Color.Green
Label1.Text = DateTime.Now.ToString("HH:mm:ss.ffff") ' just to show it's "clicking"
End Sub
End Class
Okay, here's a little example of my program, which shows my problem.
This is the interface:
enter image description here
When I press F1, the counter starts to add 1 to itself, when I press F2, the counter stops. The Select button changes F1 to F9 or F2 to F10, but when I change the key the function is triggered, that is, if the counter is stopped, and the key is at F1, when I click Select to change from F1 to F9, the counter is activated.
Here is an example of the code, so you can see the problem first hand:
Public Class Form1
Declare Function GetAsyncKeyState Lib "user32" (ByVal vKeys As Integer) As Short
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Label1.Text += 1
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
Dim a, b As Boolean
If TextBox1.Text = "F1" Then
a = GetAsyncKeyState(Keys.F1)
ElseIf TextBox1.Text = "F9" Then
a = GetAsyncKeyState(Keys.F9)
End If
If TextBox2.Text = "F2" Then
b = GetAsyncKeyState(Keys.F2)
ElseIf TextBox2.Text = "F10" Then
b = GetAsyncKeyState(Keys.F10)
End If
If a = True Then
Timer1.Start()
ElseIf b = True Then
Timer1.Stop()
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer2.Enabled = False
TextBox1.ReadOnly = False
TextBox1.Text = "Press any key"
TextBox1.Focus()
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
e.SuppressKeyPress = True
If TextBox1.ReadOnly = False Then
If e.KeyCode = Keys.F9 Then
TextBox1.Text = "F9"
Else
TextBox1.Text = "F1"
End If
End If
Timer2.Enabled = True
TextBox1.ReadOnly = True
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Timer2.Enabled = False
TextBox2.ReadOnly = False
TextBox2.Text = "Press any key"
TextBox2.Focus()
End Sub
Private Sub TextBox2_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox2.KeyDown
e.SuppressKeyPress = True
If TextBox2.ReadOnly = False Then
If e.KeyCode = Keys.F10 Then
TextBox2.Text = "F10"
Else
TextBox2.Text = "F2"
End If
End If
Timer2.Enabled = True
TextBox2.ReadOnly = True
End Sub
End Class
#Idle_Mind
I have a databound ListItems combobox with AutoComplete.SuggestAppend
and would like to navigate out of the combobox to different controls using the up/down arrow keys rather than scrolling the items.
The issue is that if the text isn't completed the suggested text remains highlighted while the next control has focus.
Link to image example
Here is some code showing a simple example of what I am doing
Public Class Form1
Dim PreventCboBoxChanging As Boolean
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ComboBox1.DataSource = New List(Of String)(New String() {10, 11, 20, 30})
ComboBox1.AutoCompleteSource = AutoCompleteSource.ListItems
ComboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend
End Sub
Private Sub ComboBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles ComboBox1.KeyDown
If PreventCboBoxChanging = True Then
e.Handled = True
End If
PreventCboBoxChanging = False
End Sub
Private Sub ComboBox1_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) Handles ComboBox1.PreviewKeyDown
If e.KeyCode = Keys.Down Or e.KeyCode = Keys.Up Then
PreventCboBoxChanging = True
TextBox1.Select()
End If
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode = Keys.Down Or e.KeyCode = Keys.Up Then
ComboBox1.Select()
End If
End Sub
Private Sub ComboBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ComboBox1.Validating
Dim index As Integer = sender.FindString(sender.Text)
If index > -1 Then
sender.SelectedIndex = index
Else
e.Cancel = True
Me.Text = ""
Beep()
End If
End Sub
End Class
Is there any way to deselect the text?
I found the solution in another thread. Needed to turn off the Combobox AutoComplete Mode, change focus then reenable SuggestAppend mode under the PreviewKeyDown event.
Private Sub ComboBox1_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) Handles ComboBox1.PreviewKeyDown
If e.KeyCode = Keys.Down Or e.KeyCode = Keys.Up Then
ComboBox1.AutoCompleteMode = AutoCompleteMode.None
TextBox1.Select()
ComboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend
End If
End Sub
This should make it:
Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
ComboBox1.SelectionLength = 0
End Sub
I am using a DataSource in my form app, and it was working fine for calls made across the board, Fill, Add, Delete, etc... It suddenly stopped working. I get no errors on build, no data is added to any ComboBoxes, and no new Adds work either.
I created a new DataSource from the same database that works fine with the exact same connection. The location of the database never moved, no changes were made to any properties of the DataSource or any of the Adapters assigned to the source, it just stopped working. Here is some screen shots and code of my form.
I tried to do a Code Compare but since there are a bunch of Adapters assigned to the source I can't find any anomalies. What would kill a data connection so that the code still sees the connection, but nothing gets filled?
The following code no longer works, no Fill or Add to DCGDataSet;
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs)
'TODO: This line of code loads data into the 'DCGDataSet1.Main' table. You can move, or remove it, as needed.
Me.MainTableAdapter.Fill(Me.DCGDataSet.Main)
Me.MainTableAdapter.Fill(Me.DCGDataSet.Main)
'comboClear()
End Sub
Private Sub btnAddNew_Click(sender As Object, e As System.EventArgs)
' Add new Job to the database
Dim newJobRow As New DCGDataSetTableAdapters.MainTableAdapter
Dim intInsert As Integer
Dim jobText = txtBoxAddNewJob.Text
intInsert = newJobRow.InsertJob(jobText)
If intInsert = 1 Then
MessageBox.Show("New Job Added")
' Update the comboBox values
Me.MainTableAdapter.Fill(Me.DCGDataSet.Main)
txtBoxAddNewJob.Text = ""
clearTabOne()
Else
MessageBox.Show("Job Not Added")
End If
End Sub
The following call for a ComboBox works fine, this is the new DataSource;
Private Sub MainForm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'DCGDataSet1.Main' table. You can move, or remove it, as needed.
Me.MainTableAdapter1.Fill(Me.DCGDataSet1.Main)
End Sub
These pics are of the two DS I am working with, the top one is the non-working DS.
Entire .vb of Form1 Code;
Public Class MainForm
Dim strCurrency As String = ""
Dim acceptableKey As Boolean = False
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'DCGDataSet1.Main' table. You can move, or remove it, as needed.
Me.MainTableAdapter.Fill(Me.DCGDataSet.Main)
Me.MainTableAdapter.Fill(Me.DCGDataSet.Main)
comboClear()
End Sub
Private Sub btnAddNew_Click(sender As Object, e As System.EventArgs)
' Add new Job to the database
Dim newJobRow As New DCGDataSetTableAdapters.MainTableAdapter
Dim intInsert As Integer
Dim jobText = txtBoxAddNewJob.Text
intInsert = newJobRow.InsertJob(jobText)
If intInsert = 1 Then
MessageBox.Show("New Job Added")
' Update the comboBox values
Me.MainTableAdapter.Fill(Me.DCGDataSet.Main)
txtBoxAddNewJob.Text = ""
clearTabOne()
Else
MessageBox.Show("Job Not Added")
End If
End Sub
Private Sub TabPage2_Enter(sender As Object, e As System.EventArgs)
Me.ActiveControl = txtBoxAddNewJob
clearTabOne()
End Sub
Public Sub comboClear()
ComboBox1.SelectedIndex = -1
ComboBox2.SelectedIndex = -1
End Sub
Private Sub TabPage1_Enter(sender As Object, e As System.EventArgs)
'comboClear()
ComboBox1.SelectedIndex = -1
'ComboBox1.SelectedText = ""
End Sub
Private Sub TabPage3_Enter(sender As Object, e As System.EventArgs)
'comboClear()
ComboBox2.SelectedIndex = -1
clearTabOne()
End Sub
Private Sub btnDeleteJob_Click(sender As Object, e As System.EventArgs)
Dim delJobID = ComboBox2.SelectedValue
Dim delJobRowAdpt As New DCGDataSetTableAdapters.MainTableAdapter
Dim delJobRow As DCGDataSet.MainRow
Dim intDelete As Integer
delJobRow = DCGDataSet.Main.FindByID(delJobID)
delJobRow.Delete()
intDelete = delJobRowAdpt.Update(DCGDataSet.Main)
If intDelete = 1 Then
MessageBox.Show("Job Deleted")
'comboClear()
clearTabOne()
'ComboBox2.SelectedValue = -1
Me.MainTableAdapter.Fill(Me.DCGDataSet.Main)
Else
MessageBox.Show("Job Failed to Delete")
End If
ComboBox2.SelectedValue = -1
End Sub
Private Sub FillSubCombo(ByVal subJob As String)
Dim selSubRow = DCGDataSet.SubBilling
Dim selSubValue As New DCGDataSetTableAdapters.SubBillingTableAdapter
Me.SubBillingTableAdapter.SubName(Me.DCGDataSet.SubBilling, subJob)
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As System.EventArgs)
Dim subJob As String = ComboBox1.Text
If subJob.Length > 1 Then
Label5.Visible = True
ComboBox3.Visible = True
FillSubCombo(subJob)
End If
End Sub
Public Sub clearTabOne()
Label5.Visible = False
ComboBox3.Visible = False
End Sub
Private Sub TabPage4_Enter(sender As Object, e As System.EventArgs)
clearTabOne()
End Sub
Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
If (e.KeyCode >= Keys.D0 And e.KeyCode <= Keys.D9) OrElse (e.KeyCode >= Keys.NumPad0 And e.KeyCode <= Keys.NumPad9) OrElse e.KeyCode = Keys.Back Then
acceptableKey = True
Else
acceptableKey = False
End If
End Sub
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
' Check for the flag being set in the KeyDown event.
If acceptableKey = False Then
' Stop the character from being entered into the control since it is non-numerical.
e.Handled = True
Return
Else
If e.KeyChar = Convert.ToChar(Keys.Back) Then
If strCurrency.Length > 0 Then
strCurrency = strCurrency.Substring(0, strCurrency.Length - 1)
End If
Else
strCurrency = strCurrency & e.KeyChar
End If
If strCurrency.Length = 0 Then
TextBox1.Text = ""
ElseIf strCurrency.Length = 1 Then
TextBox1.Text = "0.0" & strCurrency
ElseIf strCurrency.Length = 2 Then
TextBox1.Text = "0." & strCurrency
ElseIf strCurrency.Length > 2 Then
TextBox1.Text = strCurrency.Substring(0, strCurrency.Length - 2) & "." & strCurrency.Substring(strCurrency.Length - 2)
End If
TextBox1.Select(TextBox1.Text.Length, 0)
End If
e.Handled = True
End Sub
Private Sub MainForm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'DCGDataSet1.Main' table. You can move, or remove it, as needed.
Me.MainTableAdapter1.Fill(Me.DCGDataSet1.Main)
End Sub
End Class
Your not-working code is missing the Handles clauses on Form1_Load and btnAddNew_Click. If you don't connect the event handler to the event (using either a Handles clause or an AddHandler statement), the event handler won't be run.
I am writing a calculator WinForm in VB. I have a label used to display the output "Result". My problem comes when trying to add a "." to my label string. Example: I will type 355.5 and until the 5 is pressed after it, my string is showing up as .355 After the last 5 is pressed, it jumps into the correct location. I have exhausted my debugging skill and now am just going crazy. Anyone encounter this before?
Here's my entire code so far (ignore unfinished functions)
Public Class MyCalc
Private bDecFlag As Boolean
Private sMathOp As String
Private Sub ModeSel_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ModeSel.SelectedIndexChanged
If ModeSel.SelectedIndex = 3 Then
Me.Width = 360
ElseIf ModeSel.SelectedIndex > 2 Then
Me.Width = 590
Else
Me.Width = 250
End If
If ModeSel.SelectedIndex = 0 Then
For iCount As Integer = 0 To 9
Me.Controls("Digit" & iCount).Enabled = True
Next
End If
If ModeSel.SelectedIndex = 1 Then
For iCount As Integer = 2 To 9
Me.Controls("Digit" & iCount).Enabled = False
Next
End If
If ModeSel.SelectedIndex = 2 Then
For iCount As Integer = 0 To 7
Me.Controls("Digit" & iCount).Enabled = True
Next
Digit8.Enabled = False
Digit9.Enabled = False
End If
If ModeSel.SelectedIndex = 3 Then
For iCount As Integer = 0 To 9
Me.Controls("Digit" & iCount).Enabled = True
Next
For iCount As Integer = Asc("A") To Asc("F")
Me.Controls("Alpha" & Chr(iCount)).Enabled = True
Next
For iCount As Integer = Asc("G") To Asc("Z")
Me.Controls("Alpha" & Chr(iCount)).Enabled = False
Next
End If
If ModeSel.SelectedIndex = 4 Then
For iCount As Integer = 0 To 9
Me.Controls("Digit" & iCount).Enabled = True
Next
For iCount As Integer = Asc("A") To Asc("Z")
Me.Controls("Alpha" & Chr(iCount)).Enabled = True
Next
AlphaA.Enabled = False
AlphaE.Enabled = False
AlphaI.Enabled = False
AlphaO.Enabled = False
AlphaU.Enabled = False
End If
End Sub
Private Sub Digit0_Click(sender As System.Object, e As System.EventArgs) Handles Digit0.Click
UpdateResult(0)
End Sub
Private Sub Digit1_Click(sender As System.Object, e As System.EventArgs) Handles Digit1.Click
UpdateResult(1)
End Sub
Private Sub Digit2_Click(sender As System.Object, e As System.EventArgs) Handles Digit2.Click
UpdateResult(2)
End Sub
Private Sub Digit3_Click(sender As System.Object, e As System.EventArgs) Handles Digit3.Click
UpdateResult(3)
End Sub
Private Sub Digit4_Click(sender As System.Object, e As System.EventArgs) Handles Digit4.Click
UpdateResult(4)
End Sub
Private Sub Digit5_Click(sender As System.Object, e As System.EventArgs) Handles Digit5.Click
UpdateResult(5)
End Sub
Private Sub Digit6_Click(sender As System.Object, e As System.EventArgs) Handles Digit6.Click
UpdateResult(6)
End Sub
Private Sub Digit7_Click(sender As System.Object, e As System.EventArgs) Handles Digit7.Click
UpdateResult(7)
End Sub
Private Sub Digit8_Click(sender As System.Object, e As System.EventArgs) Handles Digit8.Click
UpdateResult(8)
End Sub
Private Sub Digit9_Click(sender As System.Object, e As System.EventArgs) Handles Digit9.Click
UpdateResult(9)
End Sub
Private Sub DecBut_Click(sender As System.Object, e As System.EventArgs) Handles DecBut.Click
If bDecFlag = False Then
If Result.Text = "0" Then
Result.Text = "0."
bDecFlag = True
Else
Result.Text = Result.Text + "."
bDecFlag = True
End If
End If
End Sub
Private Sub ClrBut_Click(sender As System.Object, e As System.EventArgs) Handles ClrBut.Click
Result.Text = 0
bDecFlag = False
End Sub
Private Sub DelBut_Click(sender As System.Object, e As System.EventArgs) Handles DelBut.Click
If Result.Text = "0" Then
ElseIf Result.Text.Substring(Result.Text.Length - 1) = "." Then
Result.Text = Result.Text.Substring(0, Result.Text.Length - 1)
bDecFlag = False
Else
Result.Text = Result.Text.Substring(0, Result.Text.Length - 1)
If Result.Text = "" Then
Result.Text = "0"
End If
End If
End Sub
Private Sub MyCalc_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Select Case e.KeyCode
Case Keys.NumPad0
Digit0_Click(Digit0, New EventArgs)
Case Keys.NumPad1
Digit1_Click(Digit1, New EventArgs)
Case Keys.NumPad2
Digit2_Click(Digit2, New EventArgs)
Case Keys.NumPad3
Digit3_Click(Digit3, New EventArgs)
Case Keys.NumPad4
Digit4_Click(Digit4, New EventArgs)
Case Keys.NumPad5
Digit5_Click(Digit5, New EventArgs)
Case Keys.NumPad6
Digit6_Click(Digit6, New EventArgs)
Case Keys.NumPad7
Digit7_Click(Digit7, New EventArgs)
Case Keys.NumPad8
Digit8_Click(Digit8, New EventArgs)
Case Keys.NumPad9
Digit9_Click(Digit9, New EventArgs)
Case Keys.Back
DelBut_Click(DelBut, New EventArgs)
Case Keys.Decimal
DecBut_Click(DecBut, New EventArgs)
End Select
End Sub
Private Sub MyCalc_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
bDecFlag = False
End Sub
Public Sub UpdateResult(ByVal sNum As String)
If Result.Text = "0" Then
Result.Text = sNum
Else
Result.Text &= sNum
End If
End Sub
End Class
So after the long debugging, I found out that you are using the Label/Textbox RightToLeft property set to yes. Nothing is wrong with it really, but it can't handle special characters including decimal points, commas, etc. properly. The workaround for this is to reverse what we have expected - to reverse the string concatenation.
Result.Text = "." & Result.Text
Not seeing entire code I'm not exactly sure but I think there might be something wrong with string concatenation.
Try changing into this:
Result.Text = Result.Text & "."
I have a form with over 10 textboxes and 1 button, I would like to disable the button with a realtime validation until all textboxes filled with a 10 or a 13 length numeric value, my code is the following so far:
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
For Each userID As Control In Me.Controls.OfType(Of TextBox)()
AddHandler userID.TextChanged, AddressOf ValidateAllFields
Next userID
End Sub
Private Sub userID_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles Me.KeyPress
If e.KeyChar <> ChrW(Keys.Back) Then
If Char.IsNumber(e.KeyChar) Then
Else
e.Handled = True
End If
End If
End Sub
Private Function ValidateAllFields()
Dim Validation As Boolean = True
For Each userID As Control In Me.Controls.OfType(Of TextBox)()
Dim e As New System.ComponentModel.CancelEventArgs
e.Cancel = False
Call userID_Validating(userID, e)
If e.Cancel = True Then Validation = False
Next userID
buttonSave.Enabled = Not Me.Controls.OfType(Of TextBox).Any(Function(userID) userID.Text.Length <> 10 AndAlso userID.Text.Length <> 13)
Return Validation
End Function
Private Sub userID_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles _
user00.Validating, _
user01.Validating, _
user02.Validating, _
user03.Validating, _
user04.Validating, _
user05.Validating, _
user06.Validating, _
user07.Validating, _
user07.Validating, _
user08.Validating, _
user09.Validating, _
user10.Validating, _
user11.Validating
If Not IsNumeric(sender.Text) OrElse (sender.Text.Length <> 10) AndAlso (sender.Text.Length <> 13) Then
ErrorProvider1.SetError(sender, "")
ErrorProvider2.SetError(sender, "Please enter a valid User ID.")
e.Cancel = True
Else
ErrorProvider1.SetError(sender, "Valid User ID.")
ErrorProvider2.SetError(sender, "")
End If
End Sub
Thanks to your help it works as I wanted, but can you help me improve/clean it? I'm still studying vb, I'm open to any suggestion. Thanks in advance!
Here you have a code performing the actions you want:
Dim done1, done2, done3 As Boolean
Dim targetLength1 As Integer = 10
Dim targetLength2 As Integer = 13
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Try
If (IsNumeric(TextBox1.Text)) Then
If (TextBox1.Text.Length = targetLength1 Or TextBox1.Text.Length = targetLength2) Then
done1 = True
End If
End If
If (done1 And done2 And done3) Then
Button1.Enabled = True
End If
Catch ex As Exception
End Try
End Sub
Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged
Try
If (IsNumeric(TextBox2.Text)) Then
If (TextBox2.Text.Length = targetLength1 Or TextBox2.Text.Length = targetLength2) Then
done2 = True
End If
End If
If (done1 And done2 And done3) Then
Button1.Enabled = True
End If
Catch ex As Exception
End Try
End Sub
Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged
Try
If (IsNumeric(TextBox3.Text)) Then
If (TextBox3.Text.Length = targetLength1 Or TextBox3.Text.Length = targetLength2) Then
done3 = True
End If
End If
If (done1 And done2 And done3) Then
Button1.Enabled = True
End If
Catch ex As Exception
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Button1.Enabled = False
End Sub
It accounts just for 3 textboxes (TextBox1, TextBox2 and TextBox3) and 1 button (Button1) but you can extend the idea to as many textboxes as you wish. It relies on the TextChanged even of each textbox. When the condition is met (given textbox has a number whose length is 10 or 13), the corresponding flag is set to true (e.g., done1 for TextBox1...). When all the flags are true (all the textboxes contain the expected information), the button is disabled.
I think would better to use TextChanged Event ..
Private Sub TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged, TextBox2.TextChanged, ....., TextBox10.TextChanged
Chk4ButtonEnabled()
End Sub
Sub Chk4ButtonEnabled()
Dim s as String
For Each userID As Control In Me.Controls
If userID.GetType Is GetType(TextBox) Then
s = userID.Text
If Not s.Length = 10 OR Not s.Length = 13 Then
ErrorProvider1.SetError(userID, "")
buttonSave.Enabled = False
Else
ErrorProvider1.SetError(userID, "Valid User ID.")
buttonSave.Enabled = True
End If
End If
Next
End Sub