Highlight in Listboxes without permitting user selection - vb.net

Is there a way to highlight an item in a VB.Net listbox without
allowing the user to change selection?
When I set the selection Mode to "NONE" I canĀ“t select an item in the code.
Same when I disable the listbox.

Setting the list box' Enabled property to False works fine:
Public Class Form1
Public Sub New()
InitializeComponent()
ListBox1.Items.AddRange(New String() {"one", "two", "three"})
ListBox1.Enabled = False
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ListBox1.SelectedIndex = 1
End Sub
End Class

Related

cmbComboBox.SelectionStart always returns zero irrespective of cursor location

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

Create list box in runtime and change its color via menu in runtime

I need to write this small program in visual basic, but i face a problem which is i can't change the color or add list form text file during runtime.
this is picture of what i wont to do
http://i62.tinypic.com/30tghh0.png
And this is the code i wrote so far,,
Public Class Form1
Private Sub NewToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewToolStripMenuItem.Click
Dim listBox1 As New System.Windows.Forms.ListBox
listBox1.Text = "New List"
listBox1.Location = New Point(25, 25)
listBox1.Size = New Size(380, 280)
Me.Controls.Add(listBox1)
OpenToolStripMenuItem.Enabled = True
SaveToolStripMenuItem.Enabled = True
SaveAsToolStripMenuItem.Enabled = True
CloseToolStripMenuItem.Enabled = True
EditToolStripMenuItem.Enabled = True
End Sub
Private Sub ExirToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExirToolStripMenuItem.Click
End
End Sub
Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
If (OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK) Then
Dim myfile As String = OpenFileDialog1.FileName
Dim allLines As String() = File.ReadAllLines(myfile)
For Each line As String In allLines
ListBox1.Items.Add(line)
Next
End If
End Sub
End Class
The problem as you see is in OpenToolStripMenuItem sub with line ListBox1.Items.Add(line)
is there is no listbox1 because is not created yet.the same with color, save and the rest.
so, please help me to solve it.
Move the declaration of ListBox1 out to the Class level:
Public Class Form1
Private ListBox1 As System.Windows.Forms.ListBox
Private Sub NewToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewToolStripMenuItem.Click
ListBox1 = New System.Windows.Forms.ListBox
...
End Sub
...
End Class
*But why create it at run-time like this? You could add it at design-time and set the Visible() property to False. When the New button is clicked, you change Visible() to True. Unless you need a new ListBox to be created each time so you have more than one? If so, how will they be laid out?...

How to select TextBox on Label Click

In Microsoft Access, when you click on a label, the textbox associated with that label gets the focus. As far as I can tell, VB.NET does not have this same functionality. I know I can always add something in to the click event of the label, like so...
TextBox1.Focus()
But I have dozens of fields on the form, and it would make it so much easier if I did not need to add this to the click event of each label.
I guess it would be possible to make an event for all labels that forces a tab to the next control, and assuming that I have the Tab indices set up correctly, then this would work. The problem would occur when adding new fields to the form, in which case all tab indices would need re-verified.
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click, Label2.Click
'code to tab to next field...
End Sub
Is there any easier way?
First, set the controls' TabIndex orders on your form then use this code:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each c As Control In Me.Controls
If TypeOf c Is Label Then AddHandler c.Click, AddressOf Label_Click
Next
End Sub
Private Sub Label_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Me.SelectNextControl(sender, True, True, True, True)
End Sub
End Class
Now whenever you click on a label, the following control in the order will be focused.
How about creating a dictionary where the label is the key and the control to focus is the value, then add a Click event handler to all of the label in the Dictionary. Everytime you add a label/control 'all' you need to do is add another KeyValuePair to the Dictionary
Simple Example:
Public Class Form1
Protected Friend DicLabelToControl As Dictionary(Of Label, Control)
Protected Friend Sub InitLabelDic()
DicLabelToControl = New Dictionary(Of Label, Control) From {{Label1, TextBox1}, {Label2, TextBox2}}
End Sub
Protected Friend Sub AddClickEventsToLabels()
For Each lb As Label In DicLabelToControl.Keys
AddHandler lb.Click, AddressOf HandleLabelClick
Next
End Sub
Private Sub HandleLabelClick(sender As Object, e As EventArgs)
DicLabelToControl(CType(sender, Label)).Focus()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitLabelDic()
AddClickEventsToLabels()
End Sub
End Class

Get combobox selected from another form dynamically

I have a combobox in a form1 and a datagridview in another form2.
I want to get the combobox selected with a value from the datagridview in the second form
I use the code below in form2 and it works:
Private Sub DataGridView1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
form1.CBO_fournisseur.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
Me.Close()
End Sub
But what I want to do is that the name of the form is passed dynamically to avoid using and IFELSE clause to enumerate all the forms I have in my project that use form2
Private Sub DataGridView1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
If formbon2.Name = "FRM_BN_RECEPTION_CUIR" Then
FRM_BN_RECEPTION_CUIR.CBO_fournisseur.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
ElseIf formbon2.Name = "frm_reception_acc_provisoire" Then
frm_reception_acc_provisoire.CBO_1.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
End If
Me.Close()
End Sub
I think I've got what you want to do. I strongly suggest you stop using the Form as a Shared resource.
Use a constructor like this in your Form2:
Private ParentFormCombo as Combobox
Public Sub New(ByVal pCmb as Combobox)
ParentFormCombo = pCmb
End Sub
Then in your doubleclick you just change the text of ParentFormCombo
ParentFormCombo.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
Then you have to stop using:
FrmList_View.Show()
Now you should always use the constructor instead (New()). So do the following instead:
Dim f As New FrmList_View(CBO_fournisseur)
'or
Dim f As New FrmList_View(CBO_1)
f.Show()

Making combobox visible when it is disabled

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