For a combobox, selectedIndex returns 0 while selectedtext returns a value - vb.net

Once I select a value from a Combobox and save the form, ComboBox.SelectedText contains the value selected but ComboBox.SelectedIndex is returning 0 always for each item in the list. Below is just a sample code for reference.
If (combobox1.SelectedIndex = 0 Or combobox1.SelectedText = "")
MessageBox.Show("No value selected")
else
MessageBox.Show("Some value selected")
End If

Some code to illustrate usage
Private Sub ComboBox1_SelectedIndexChanged(sender As Object,
e As EventArgs) Handles ComboBox1.SelectedIndexChanged
'check for no item selected
If ComboBox1.SelectedIndex < 0 Then
Stop 'no item
Else
Dim idx As Integer = ComboBox1.SelectedIndex
Dim val As String = CStr(ComboBox1.SelectedItem) '<-- use SelectedItem
Stop
End If
End Sub

Small Answer
SelectedText is not the same as SelectedItem. Take a look at ComboBox.SelectedText:
Gets or sets the text that is selected in the editable portion of a ComboBox.
I think that you are confusing this with ComboBox.SelectedItem
SelectedIndex: -1 if nothing selected, otherwise the index of the selected item
SelectedValue: null if nothing selected, otherwise the selected item
SelectedText: the text that the operator marked in the editable part of the combo box.
** Room for improvement **
You use VB. My VB is a bit rusty, so I'll give my answer in C#. I guess you'll get the gist.
In Winforms, whenever you want to fill a that shows a sequence of items, like ComboBoxes, ListBoxes, DataGridViews, Charts, etc, there are usually two methods:
Fill the ComboBox one by one with the texts that you want to display
Use a DataSource: fill it with the Items that you want to be selectable, and tell the ComboBox which property of the selectable items you want to display.
Use the first method if you only want to display a constant array of strings. Fill ComboBox.Items. When an item is selected, use SelectedIndex to get the index of the selected string. Use ComboBox.Items[selectedIndex] to get the selected string.
If the string represents something more than just a string, for instance the text represents a Customer, or a Product. It is usually easier to use the DataSource method.
To do that, you use property ComboBox.DataSource to tell the ComboBox which Customersit should display. In ComboBox.ValueMember you tell the ComboBox which Customer poperty should be used to represent the Customer, for instance the name of the Customer.
Once the operator selected the name of the Customer, you get the complete Selected Customer using property ComboBox.SelectedItem:
List<Customer> availableCustomers = ...
ComboBox combo1 = new ComboBox(...);
combo1.ValueMember = nameof(Customer.Name); // the Customer property that you want to display
combo1.DataSource = availableCustomers;
After the operator selected an item, you can process the event, and fetch the selected customer immediately:
Customer selectedCustomer = (Customer)cmbo1.SelectedValue;
ProcessSelectedCustomer(selectedCustomer);
Of course you should only select a property that is unique. If you have two Customers named "Hans Brinker", operators wouldn't know which name represents which Customer.
Apart from the nice thing that you don't have to do a lookup from SelectedIndex to what this selected item represents (a Customer), you are independent of the order in which the Customers are displayed.
Another nice thing: if in future versions you want to change from ComboBox to ListBox, or maybe even to DataGridView, you won't have to change your model drastically: the control still shows a sequence of Customers, and once an operator selects something that represents this Customer (Name? Id?, DataGridView Row?), you get the complete Customer.

(1)ComboBox1.SelectedIndex starts from -1, when you are not selected, ComboBox1.SelectedIndex=-1
(2)When you click combobox1.items, SelectedText is always "".
This is because, at the time of these events(SelectedIndexChanged, SelectedValueChanged.. ), the previous SelectedText value has been cleared and the new value has not yet been set. You can use the SelectedItem property instead.
E.g:combobox1.SelectedItem
Please try the following code.
If ComboBox1.SelectedIndex = -1 Then
MessageBox.Show("No value selected")
Else
MessageBox.Show("Some value selected")
End If

Related

How can I read the SelectedItem of a Listbox?

I am trying to get the selected text in a ListBox to show in a list box.
I have a button that when I click, will show the text of a Selected item in a ListBox.
I've already tried getting the list box to show the text in a textbox using Listbox.SelectedItem:
Listbox1.SelectedItem = Textbox1.Text
When I do this, I get the error:
System.NullReferenceException: 'Object variable or With block variable
not set.'
Your description is somewhat upside-down.
It's not clear whether you want to set a ListBox.SelectedItem using the Text of a TextBox or you want to set a TextBox.Text with the text of the SelectedItem of a ListBox.
The code says one thing, the description another. The error you have is probably caused by a null SelectedItem (you haven't selected anything).
But, if you want to set a TextBox.Text with the ListBox.SelectedItem text, you can use the GetItemText() method. This method has a plus, it won't raise an exception if the Listbox has no selected Items (the SelectedItem is null (nothing)).
TextBox1.Text = ListBox1.GetItemText(ListBox1.SelectedItem)
The opposite:
You can use the ListBox FindString() and FindStringExact() methods to locate an item in the control's collection corresponding to a given string.
The former finds the first items in the ListBox that starts with the specified string, the latter matches only the whole string.
The search can begin from a specific index. It's not case sensitive.
listBox1.SelectedIndex = listBox1.FindString(textBox1.Text, 0)
' or
listBox1.SelectedIndex = listBox1.FindStringExact(textBox1.Text, 0)
You can continue the search specifying, as the starting point, the index of the item previously found:
private int lboxSearchIndex = -1;
Private Sub ButtonSearch_Click(sender As Object, e As EventArgs) Handles ButtonSearch.Click
lboxSearchIndex = listBox1.FindString(textBox1.Text, lboxSearchIndex)
listBox1.SelectedIndex = lboxSearchIndex
End Sub
Setting the SelectedItem is like using the FindStringExact() method.
Only a full match will set the item, but it's case sensitive.
Listbox1.Text=textbox1.text
Let me know its help you

Monitoring Datagridview for rows that are being unhidden

I've got a a bit of code that is allowing a Results box to pop up, populating a DataGridView with information. The DataGridView uses the same BindingSource that another DataGridView uses, so when one is clicked, the other automatically moves to the same selected cell.
The issue I am having is the Result_DataGridView doesn't always contain all of the same rows as the master DGV, as it hides rows that don't match a criteria. If the user clicks on a cell on the Master DGV that isn't present in the Result DGV, the Result DGV un-hides that row (as you can't hide a selected row).
I'm currently trying to use this method to hide the row that appears again, but because of how VB treats "Entering a cell" it fires before the cell actually appears (as it fires on input focus, but before the cell actually appears in the DGV, so that row never gets checked)
Private Sub Result_Datagridview_CellEnter(sender As Object, e As DataGridViewCellEventArgs) Handles Result_Datagridview.CellEnter
Dim Result As Integer
Dim i
For row As Integer = 0 To Result_Datagridview.RowCount - 1
i = row
Result = Array.Find(ResultArray, Function(x) x = Result_Datagridview.Rows(i).Cells(0).Value)
If Result = 0 Then
Result_Datagridview.Rows(i).Visible = False
End If
Next
End Sub
If there was a ".RowsUnhidden" event, this would work fine.
Note - the ResultArray contains all of the index numbers that need to remain visible, the check is performed to see if any rows exist with an index number that does not appear in the array, if so, hide it again.
Does anyone have a work around or better approach to this?
Handling the RowEnter event, you can suspend the binding and reset row.Visible to False.
So, if ResultArray is an Integer array of visible row indices, you simply do the following:
Private Sub Result_Datagridview_RowEnter(sender As Object, e As DataGridViewCellEventArgs)
If Not ResultArray.Contains(e.RowIndex) Then
Dim currencyManager1 As CurrencyManager = DirectCast(BindingContext(Result_Datagridview.DataSource), CurrencyManager)
currencyManager1.SuspendBinding()
Result_Datagridview.Rows(e.RowIndex).Visible = False
currencyManager1.ResumeBinding()
End If
End Sub
You can look at the DataGridView.CellStateChanged event. It occurs when a cell get the focus, lose it, is selected, ...

collecting textbox text with checkboxlist item using vb.net

am building a task management system using vb.net. How to set a textbox field beside each checkboxlist so when the user tick the checkbox he can comment too for this item and submit the whole finished tasks ? below is my code
Sub GetGroups()
cblGroups.DataSource = Task.Components.Tasks.GetAllTasks
cblGroups.DataTextField = "TaskName"
cblGroups.DataValueField = "ID"
cblGroups.DataBind()
End Sub
For Each item As ListItem In cblGroups.Items
If item.Selected Then
'reading each item value
End if
Next
I think you should be using a DataGridView instead. In there you can have a checkbox column and a textbox column, also a new row placeholder to put new tasks. If you don't like DataGridView, you can use alternatives.
Your other option would be to maintain a list of CheckBox controls and their TextBox pairs, essentially doing data grid's job. You are okay at first, but then you may need scrolling etc., so why not use a built-in control, where such issues are already solved out of the box.
'Check through each of the items
For Each item As ListItem In cblGroups.Items
'If this particular item is checked
If item.Selected = True Then
'Dynamically create a HTML Textbox
item.Text = [String].Format("{0}<input id=""TextBox{0}"" name=""TextBox{0}"" / >", item.Text)
Else
'Otherwise simply store the normal value
item.Text = [String].Format("{0}", item.Text)
End If
Next

How do I set a VB.Net ComboBox default value

I can not locate the correct method to make the first item in a combo box visible.
The app starts with an empty combo box. The user makes a radio box selection then clicks Go! (how original). The combo box is loaded via an LDAP query. All this is working just fine. The problem is the combo box still appears to the user to be empty. They must click the arrow to see the options.
How do I make the first option 'visible' after the users clicks Go!?
' Your code filling the combobox '
...
If myComboBox.Items.Count > 0 Then
myComboBox.SelectedIndex = 0 ' The first item has index 0 '
End If
Just go to the combo box properties - DropDownStyle and change it to "DropDownList"
This will make visible the first item.
OR
you can write this down in your program
Private Sub ComboBoxExp_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)Handles MyBase.Load
AlarmHourSelect.Text = "YOUR DEFAULT VALUE"
AlarmMinuteSelect.Text = "YOUR DEFAULT VALUE"
End Sub
so when you start your program, the first thing it would do is set it on your assigned default value and later you can easily select your required option from the drop down list.
also keeping the DropDownStyle to DropDownList would make it look more cooler.
-Starkternate
because you have set index is 0 it shows always 1st value from combobox as input.
Try this :
With Me.ComboBox1
.DropDownStyle = ComboBoxStyle.DropDown
.Text = " "
End With
You can try this:
Me.cbo1.Text = Me.Cbo1.Items(0).Tostring
If ComboBox1.SelectedIndex = -1 Then
ComboBox1.SelectedIndex = 0
End If
Much simpler solution, Select the Combo-box, and in the option of Selected item, select the item index (0 for the first item) and set it to be the default value in the combo box.
Another good method for setting a DropDownList style combobox:
Combox1.SelectedIndex = Combox1.FindStringExact("test1")

How to switch between DataGridViewTextBoxCell and DataGridViewComboBoxCell?

I want to have a DataGridView that has two columns. The first column will always be of type DataGridViewComboBoxColumn. Based on the selection in that column, I'd like to be able to change the corresponding cell in the second column to either a DataGridViewComboBoxCell or a DataGridViewTextBoxCell.
I'm thinking I just need to make the second column of type DataGridViewColumn, but don't understand the mechanics of how to change the cell type on the fly.
I'm working with VB.NET in Visual Studio 2005.
Thanks in advance!
Update: One way around it, I suppose, is to make the second column as a DataGridViewComboBoxColumn, and change the attributes of the cell so that it either behaves like a drop-down list, or as an (editable) drop-down with no elements. The latter looks enough like a text box that I could live with it, and it wouldn't involve changing the type of the cell.
I don't have the VB.Net version,but hopefully this quick C# snippet will help you or point you in the right direction.
In this example, I set up a simple DataGridView with 2 columns. The first being a DataGridViewComboBox populated with two choices: "Text" or "Combo".
The second column is initially set to DataGridViewTextBoxColumn from the designer.
I handle the CurrentCellDirtyStateChanged event on the DataGridView. I check if the cell is dirty and only check the first column (The ComboBox). You gotta call the CommitEdit to get the new value in the combo or else you will be looking at the previous value. Based on the selection in the combo box I then overwrite the cell in the 2nd column with a new cell of that type.
You would add your own logic (populate the drop downs and handle the value). You might want to store the value and then put it back into the cell or whatever.
Here is the code I used and did a quick and dirty test on:
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty == false)
{
return;
}
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
if (dataGridView1.CurrentCell.ColumnIndex == 0)
{
if (((string)dataGridView1.CurrentCell.Value) == "Text")
{
dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1] = new DataGridViewTextBoxCell();
}
else if (((string)dataGridView1.CurrentCell.Value) == "Combo")
{
dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1] = new DataGridViewComboBoxCell();
}
}
}
Here is a quick VB translation, that I tested and works.
Public Class Form1
Private Sub DataGridView1_CurrentCellDirtyStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
If DataGridView1.IsCurrentCellDirty = False Then
Return
End If
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
If DataGridView1.CurrentCell.ColumnIndex = 0 Then
If CStr(DataGridView1.CurrentCell.Value) = "Text" Then
DataGridView1.Rows(DataGridView1.CurrentCell.RowIndex).Cells(1) = New DataGridViewTextBoxCell
ElseIf CStr(DataGridView1.CurrentCell.Value) = "Combo" Then
DataGridView1.Rows(DataGridView1.CurrentCell.RowIndex).Cells(1) = New DataGridViewComboBoxCell
End If
End If
End Sub
End Class
You will lose any value stored in that column, so you would need to save it first.
Jon
You can create your own cell template that hosts a user control. In the user control you add a textbox and a combobox, and add a method/property to show one and hide another.
This sample creates a radio button cell, it is not hard to change the code to host a user control.
dgvCell = new DataGridViewTextBoxCell(); // code to remove checkbox
dgvCell.Value = string.Empty;
dgv_modi_del_trans.Rows[1].Cells[0] = dgvCell;