There are people which try to solve such problem on entering to textbox. And they solved that more or less successfully.
I am trying to do same thing with NumericUpDown control by subclassing it pretty unsuccessfully.
Here is my code:
Public Class xNumericUpDown
Inherits NumericUpDown
Private _focused As Boolean
Protected Overrides Sub OnEnter(ByVal e As EventArgs)
MyBase.OnEnter(e)
If MouseButtons = MouseButtons.None Then
Me.Select(0, Me.Text.Length)
_focused = True
End If
End Sub
Protected Overrides Sub OnLeave(ByVal e As EventArgs)
MyBase.OnLeave(e)
_focused = False
End Sub
Protected Overrides Sub OnMouseUp(ByVal mevent As MouseEventArgs)
MyBase.OnMouseUp(mevent)
If Not _focused Then
If Me.Text.Length = 0 Then
Me.Select(0, Me.Text.Length)
End If
_focused = True
End If
End Sub
End Class
This selects All by entering with keyboard but dont work when selecting control with mouse.
Any help with solving that problem would be appreciated.
You will probably kick yourself, but try changing your code to this:
If Me.Text.Length > 0 Then
Me.Select(0, Me.Text.Length)
End If
Related
I'm new to VB.NET and I was experimenting with trying to call a Sub from another. I have the first Sub that handles a button then executes some code. I then want to call the other Sub I have that handles a rectangle being tapped. I'm having trouble call the second Sub from the first Sub. I think it might be the EventArgs. The first Sub is RoutedEventsArgs and the second is TappedRoutedEventArgs. I can't seem to find any documentation about this particular instance. I only see if it as the same e.
Public Class MainPage
Private Sub Show_Message(sender As Object, e As RoutedEventArgs) Handles Button_1.Click
If Message.Visibility = Visibility.Collapsed Then
Message.Visibility = Visibility.Visible
Else
Message.Visibility = Visibility.Collapsed
End If
ChangeColorItem_Click(sender, e)
End Sub
Private Sub ChangeColorItem_Click(sender As Object, e As TappedRoutedEventArgs) Handles Rectangle.Tapped
'Change fill color to red to blue and back
If rectangleFill.Color = (Windows.UI.Colors.Red) Then
rectangleFill.Color = Windows.UI.Colors.Blue
Else
rectangleFill.Color = Windows.UI.Colors.Red
End If
End Sub
End Class
I want it so that if Show_Message is run also run the ChangeColorItem_Click.
RoutedEventArgs is a square peg, TappedRoutedEventArgs is a round hole... you're trying to put a square peg in a round hole... and you don't need to.
Unless there's a need for the event args, and I don't see the event args being used, you're better off putting the code into their own sub and simply calling it.
Public Class MainPage
Private Sub Show_Message(sender As Object, e As RoutedEventArgs) Handles Button_1.Click
ShowMessage()
End Sub
Private Sub ChangeColorItem_Click(sender As Object, e As TappedRoutedEventArgs) Handles Rectangle.Tapped
ChangeColorItem()
End Sub
Private Sub ShowMessage()
If Message.Visibility = Visibility.Collapsed Then
Message.Visibility = Visibility.Visible
Else
Message.Visibility = Visibility.Collapsed
End If
ChangeColorItem()
End Sub
Private Sub ChangeColorItem()
'Change fill color to red to blue and back
If rectangleFill.Color = (Windows.UI.Colors.Red) Then
rectangleFill.Color = Windows.UI.Colors.Blue
Else
rectangleFill.Color = Windows.UI.Colors.Red
End If
End Sub
End Class
For some reason the "SelectionStart" property behaves differently from TextBox to ComboBox.
Create a TextBox and a ComboBox. Make sure DropDownStyle = DropDown (NOT DropDownList!)
Add these Leave events (same result if you use LostFocus event):
Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave
Debug.Print("Textbox: " & TextBox1.SelectionStart)
End Sub
Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
Debug.Print("ComboBox: " & ComboBox1.SelectionStart)
End Sub
Now type text into each control and change focus from control to control, with the selection cursor in different places in the string.
I get this:
Textbox: 6
ComboBox: 0
Textbox: 8
ComboBox: 0
Textbox: 5
ComboBox: 0
Textbox: 4
ComboBox: 0
... and so on
When the textbox loses focus, it returns the correct SelectionStart.
When the combobox loses focus, it always returns zero.
Is there a reason, solution or reasonable workaround? I cannot seem to intercept this without creating a new variable for each combo control, and storing the SelectionStart on every click and keypress event (assuming the user might click the mouse, use arrow keys or type characters).
I just did some testing and it appears that the selection is reset between the Leave and LostFocus events as well as between the Enter and GotFocus events. I tried remembering the values on the first of each pair and restoring it on the second and it worked as desired:
Private comboBox1SelectionStart As Integer
Private comboBox1SelectionLength As Integer
Private Sub ComboBox1_Enter(sender As Object, e As EventArgs) Handles ComboBox1.Enter
comboBox1SelectionStart = ComboBox1.SelectionStart
comboBox1SelectionLength = ComboBox1.SelectionLength
End Sub
Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
comboBox1SelectionStart = ComboBox1.SelectionStart
comboBox1SelectionLength = ComboBox1.SelectionLength
End Sub
Private Sub ComboBox1_GotFocus(sender As Object, e As EventArgs) Handles ComboBox1.GotFocus
ComboBox1.SelectionStart = comboBox1SelectionStart
ComboBox1.SelectionLength = comboBox1SelectionLength
End Sub
Private Sub ComboBox1_LostFocus(sender As Object, e As EventArgs) Handles ComboBox1.LostFocus
ComboBox1.SelectionStart = comboBox1SelectionStart
ComboBox1.SelectionLength = comboBox1SelectionLength
End Sub
You don't want to have to do that every time for every CokmboBox so you can build it into a custom control and then use that in place of the standard control:
Public Class ComboBoxEx
Inherits ComboBox
Private selectionStartTemp As Integer
Private selectionLengthTemp As Integer
Protected Overrides Sub OnEnter(e As EventArgs)
MyBase.OnEnter(e)
'Remember the current selection.
selectionStartTemp = SelectionStart
selectionLengthTemp = SelectionLength
End Sub
Protected Overrides Sub OnGotFocus(e As EventArgs)
'Restore the selection.
SelectionStart = selectionStartTemp
SelectionLength = selectionLengthTemp
MyBase.OnGotFocus(e)
End Sub
Protected Overrides Sub OnLeave(e As EventArgs)
MyBase.OnLeave(e)
'Remember the current selection.
selectionStartTemp = SelectionStart
selectionLengthTemp = SelectionLength
End Sub
Protected Overrides Sub OnLostFocus(e As EventArgs)
'Restore the selection.
SelectionStart = selectionStartTemp
SelectionLength = selectionLengthTemp
MyBase.OnLostFocus(e)
End Sub
End Class
A side-effect of this is that you will see the text selected even when the control doesn't have focus. The ComboBox has no HideSelection property like the TextBox does. If you don't like this then I'd imagine that you could find a way to make it behave like the TextBox does but that's a different question so I won't go into it here.
I think I've got it, using your idea but just setting the value in a different location.
Dim ComboSelectionStart As Integer
Private Sub cmbComboBox_KeyUp(sender As Object, e As KeyEventArgs) Handles cmbComboBox.KeyUp
'Store selection on any key press
ComboSelectionStart = cmbComboBox.SelectionStart
End Sub
Private Sub cmbComboBox_MouseClick(sender As Object, e As MouseEventArgs) Handles cmbComboBox.MouseClick
'Store selection on any mouse click
ComboSelectionStart = cmbComboBox.SelectionStart
End Sub
Private Sub cmbComboBox_Leave(sender As Object, e As EventArgs) Handles cmbComboBox.Leave
'Returns correct value here because it was not altered by LostFocus event
Debug.Print(ComboSelectionStart .ToString)
End Sub
When you modify the OnLeave() sub in the class provided by #jmcilhinney it actually works nicely.
Protected Overrides Sub OnLeave(e As EventArgs)
'Remember the current selection.
selectionStartTemp = SelectionStart
selectionLengthTemp = SelectionLength
MyBase.OnLeave(e) 'this has to go last because it modifies the SelectionStart...
End Sub
Is there a way to cancel an event through a condition? I have tried e.cancel but it does not work. After cancelling the event the dtpAudit_From.Value must revert back to its original value.
Private Sub dtpAudit_From_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtpAudit_From.ValueChanged
'check if two DTPs (Date time pickers) are valid
If dtpAudit_From.Value > dtpAudit_To.Value Then
MsgBox("cancel the event")
End If
End Sub
One way is to subclass the DateTimePicker and add a ValueChanging event. Here's an example:
Public Class UIDateTimePicker
Inherits DateTimePicker
Public Sub New()
Me.cachedValue = Me.Value
End Sub
Public Event ValueChanging As CancelEventHandler
Protected Overrides Sub OnValueChanged(e As EventArgs)
If (Not Me.reverting) Then
Dim evargs As New CancelEventArgs(False)
Me.OnValueChanging(evargs)
If ((Not evargs Is Nothing) AndAlso evargs.Cancel) Then
Dim value As Date = Me.Value
Me.reverting = True
Me.Value = Me.cachedValue
Else
Me.cachedValue = Value
MyBase.OnValueChanged(e)
End If
Me.reverting = False
End If
End Sub
Protected Overridable Sub OnValueChanging(e As CancelEventArgs)
RaiseEvent ValueChanging(Me, e)
End Sub
Private cachedValue As DateTime
Private reverting As Boolean
End Class
Usage
Private Sub dtpAudit_From_ValueChanging(sender As Object, e As CancelEventArgs) Handles dtpAudit_From.ValueChanging
e.Cancel = {Condition}
End Sub
I have such code to make all text in textbox selected on got_focus:
Private Sub myText_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles myText.GotFocus
myText.SelectAll()
End Sub
Is here a way in VB.NET to get that all TextBoxes and NumericUpDown controls selects his text on _GotFocus or _Enter without to explicitly set such behavior for every single control and no matter how this control gets a focus (keyboard, mouse or programmatic)?
Yes, there is and very simple.
Private Sub TextBox2_GotFocus(sender As Object, e As System.EventArgs) Handles TextBox2.GotFocus
TextBox2.Select(0, TextBox2.Text.Length)
End Sub
Public Class MyTextBox
Inherits System.Windows.Forms.TextBox
Private _focused As Boolean
Protected Overrides Sub OnEnter(e As EventArgs)
MyBase.OnEnter(e)
If MouseButtons = MouseButtons.None Then
SelectAll()
_focused = True
End If
End Sub
Protected Overrides Sub OnLeave(e As EventArgs)
MyBase.OnLeave(e)
_focused = False
End Sub
Protected Overrides Sub OnMouseUp(mevent As MouseEventArgs)
MyBase.OnMouseUp(mevent)
If Not _focused Then
If SelectionLength = 0 Then
SelectAll()
End If
_focused = True
End If
End Sub
End Class
I am disabling combobox in VB.net.
But in disable mode it not visible properly.
I tried changing both BackColor and ForeColor but it is not working.
Code :
cmbbox.BackColor = Color.FromName("Window")
or
cmbbox.ForeColor = Color.FromName("Window")
Please help
Dear Adam:
I am making my component enable false.But I want to make it viewable.You can reffer the link.This is what exacly I want but in VB.Net : A combobox that looks decent when it is disabled
To achieve disabling combobox without fading it, first change the dropdown style of the combobox to DropDownList, Then tweak with the events to achieve the goal.
Here is a piece of code by which you can achieve the same:
Public Class Form1
Dim selectindex As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.Items.Add("1")
ComboBox1.Items.Add("2")
ComboBox1.Items.Add("3")
ComboBox1.Items.Add("4")
selectindex = 3
ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
ComboBox1.SelectedIndex = selectindex
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted
ComboBox1.SelectedIndex = selectindex
End Sub
End Class
Create anew form Form1 and add a combobox to the form, then add the above code to get a readonly combobox.
Have a look at this thread which has a solution for a readonly combobox and the code is all VB.NET.
A version of their code is as follows. You'll need to but it inside a class of your own which inherits System.Windows.Forms.ComboBox
Private _ReadOnly As Boolean = False
Public Property [ReadOnly]() As Boolean
Get
Return _ReadOnly
End Get
Set(ByVal Value As Boolean)
_ReadOnly = Value
End Set
End Property
Public Overrides Function PreProcessMessage(ByRef msg As Message) As Boolean
'Prevent keyboard entry if control is ReadOnly
If _ReadOnly = True Then
'Check if its a keydown message
If msg.Msg = &H100 Then
'Get the key that was pressed
Dim key As Int32 = msg.WParam.ToInt32
'Ignore navigation keys
If key = Keys.Tab Or key = Keys.Left Or key = Keys.Right Then
'Do nothing
Else
Return True
End If
End If
End If
'Call base method so delegates receive event
Return MyBase.PreProcessMessage(msg)
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
'Prevent list displaying if ReadOnly
If _ReadOnly = True Then
If m.Msg = &H201 OrElse m.Msg = &H203 Then
Return
End If
End If
'Call base method so delegates receive event
MyBase.WndProc(m)
End Sub
I've been looking for the same not long ago and ended up doing the following. You may not like it, but i'll share it in case. I am using TableLayoutPanel to arrange my controls on the form and then i am swapping the positions of the desired controls.
For example I've created the following Items:
Form1 Design
TableLayoutPanel1 (two columns, three rows)
TextBox1 Read-only = True, BackColor = White
ComboBox1 Visible = False, DropDownStyle = DropDownList, FlatStyle = Popup
Button1 (named it to Change)
Button2 (named it to Done) -> Visible = False
Runtime - Screenshots
Here is my code:
Public Class Form1
Private Sub SwapControls(tlp As TableLayoutPanel, ctr1 As Control, ctr2 As Control)
Dim ctl1pos As TableLayoutPanelCellPosition = tlp.GetPositionFromControl(ctr1)
ctr1.Visible = False
tlp.SetCellPosition(ctr1, tlp.GetPositionFromControl(ctr2))
ctr2.Visible = True
tlp.SetCellPosition(ctr2, ctl1pos)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SwapControls(TableLayoutPanel1, TextBox1, ComboBox1)
SwapControls(TableLayoutPanel1, Button1, Button2)
Label1.Select()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
SwapControls(TableLayoutPanel1, ComboBox1, TextBox1)
SwapControls(TableLayoutPanel1, Button2, Button1)
Label1.Select()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Select()
ComboBox1.SelectedIndex = 0
TextBox1.Text = ComboBox1.SelectedItem
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
TextBox1.Text = ComboBox1.SelectedItem
End Sub
End Class