Programmatically Change the text of a Combox - vb.net

I have a user form with a combobox, with 5 unbound data items. The value of each item is of the following format: "## Explanation", a 2-digit numeric code and an explanation of the code. After the user selects an item, I would like to have the 2-digit numeric code displayed only. I have tried the following
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
ComboBox1.Text = Mid(ComboBox1.Text, 1, 2)
End Sub
However after selecting an item, the assignment doesn't seem to be working properly because ComboBox1.Text remains unchanged. Any ideas? Thanks in advance

To me, it sounds that you are not really using combo box to full potential. Looks like you want to have items with multiple pieces of info, which you're trying to combine. But here what you can do instead
Private Class ComboItem
Public Property Code As Integer
Public Property Description As String
Public ReadOnly Property Display As String
Get
Return Code & " " & Description
End Get
End Property
End Class
Dim lst As New List(Of ComboItem)()
lst.Add(New ComboItem()....) ' add your items
cboList.DataSource = lst
cboList.DisplayMember = "Display"
cboList.ValueMember = "Code"
Here where the best part starts - once user selects an item, by typing or clicking, you can do this
Dim item As ComboItem = DirectCast(cboList.SelectedItem, ComboItem)
txtCode.Text = item.Code
txtDescription.Text = item.Description
I feel, this is what you really need.

You would have to change the value in the combobox's Items collection. If you just change the Text property this is what happens:
Setting the Text property to null or an empty string ("") sets the SelectedIndex to -1. Setting the Text property to a value that is in the Items collection sets the SelectedIndex to the index of that item. Setting the Text property to a value that is not in the collection leaves the SelectedIndex unchanged.

Related

Trying to make smart combobox item interaction

I am here to find out is it possible to complete my idea to save me time writing long code.
I have 1 main combobox with various items and some other comboboxed. Each combobox of them is called "Combo" + the item from the main combobox.
and I wonder can I, when I click on an item to hide the last used combobox and to show the combobox linked to this item?
1. hide last used combobox
2. show the combobox responding to the selected item from the main combox
Public Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox2.SelectedIndexChanged
Dim SelectedAction As String = "Combo" + ComboBox2.Text
lastcombobox.visible = false
' now to assign to the new combobox
lastcombobox = (SelectedAction as name of combobox) combobox
Lastcombobox.visible = true
End Sub
Strings are not controls. Strings are the data type of Control.Name; that is the Name property of the control object. You cannot cast a string to a control but all is not lost. Create your other Combo Boxes at design time and stack them on top of each other. Notice the Static keyword before lastComboBox. This persists the value between calls to the method. You could accomplish the same thing by making this variable a class level variable. The first time the method is called their will be nothing in lastComboBox therefore the check for IsNothhing. Control.Find returns an array so we must refer to ctl(0) - the first element of the array, since we know it will return only one.
Private Sub Combo2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Combo2.SelectedIndexChanged
Dim SelectedAction As String = "Combo" & Combo2.Text
Static lastComboBox As ComboBox
If Not IsNothing(lastComboBox) Then
lastComboBox.Visible = False
End If
Dim ctl() As Control = Controls.Find(SelectedAction, True)
lastComboBox = CType(ctl(0), ComboBox)
lastComboBox.BringToFront()
lastComboBox.Visible = True
End Sub

VB.NET datagridview one-to-one mapping of combobox

I have a datagridview with two textbox columns and one combobox column. The combobox's DataSource is bound to enums for the values of the dropdown. The datagridview's DataSource is bound to a custom class with datatypes of string, string and enum.
The first two columns are pre-populated with values and in the third column the user must select a value from the dropdown. All this is working excellent so far except....
The combobox field should be a one-to-one kind of mapping, meaning no two comboboxes should have the same value. I am really not sure how to implement this kind of behavior. Should the chosen value be removed from the remaining dropdowns? should the chosen value remain in the dropdown and just give an error when two of the same are selected?
Any ideas and how to implement these ideas will be of great help.
Thanks
note the only acceptable value that can be used more than once is 'None'
I have an idea based off your intent to possibly remove the chosen value from the remaining dropdowns.
I have a class called Runner which has a similar setup to your example.
Public Class Runner
Public Property FirstName As String
Public Property LastName As String
Public Property Placement As Result
Public Sub New(fn As String, ln As String)
FirstName = fn
LastName = ln
Placement = Result.None
End Sub
End Class
I also have an enum called Result which will get populated into the ComboBoxCell:
Public Enum Result
None = 0
Bronze = 1
Silver = 2
Gold = 3
End Enum
When I create data objects and bind them to the DataGridView, I do so like this (note - Placements is a global List(Of Result) and Runners is a global List(Of Runner):
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Placements.Add(Result.None)
Placements.Add(Result.Bronze)
Placements.Add(Result.Silver)
Placements.Add(Result.Gold)
Runners.Add(New Runner("John", "Smith"))
Runners.Add(New Runner("Jane", "Doe"))
Runners.Add(New Runner("Bill", "Jones"))
Column1.DataPropertyName = "FirstName"
Column2.DataPropertyName = "LastName"
Column3.DataPropertyName = "Placement"
Column3.DataSource = Placements
DataGridView1.DataSource = Runners
End Sub
Now, whenever the value of a cell in the ComboBoxColumn changes, you remove the new value from the list that contains the enums:
Private Sub DataGridView1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
If (e.RowIndex > -1 And e.ColumnIndex = 2) Then
Dim currentvalue As Result = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
If currentvalue <> Result.None Then
Placements.Remove(currentvalue)
End If
End If
End Sub
Be careful when changing drop down selections... as per this Discussion, you have to trick the DataGridView into committing values as soon as the ComboBox value changes. I used an answer from that discussion and did something like this:
Private Sub DataGridView1_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
Dim col As DataGridViewColumn = DataGridView1.Columns(DataGridView1.CurrentCell.ColumnIndex)
If col.Name = "Column3" Then
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
Dim selected As DataGridViewCell = DataGridView1.CurrentCell
DataGridView1.CurrentCell = Nothing //This line and the next one simply hide
DataGridView1.CurrentCell = selected //an odd display effect that occurs
//because we remove a value and change the
//selection at the same time
End If
End Sub
Finally, you want to handle the DataError event for the DataGridView and leave it blank so that you don't get Exceptions thrown at you when removing values from your list of enums.
This gets you about 90% of the way there. It will not re-add items to the list when you change a value. For example if I change from Gold to Silver, Gold should be added back to the list. You can probably figure out what events to handle to get the old value and the new one, and insert the old value back into the list at the correct index based on its enum value.
I decided to use the CellValidating event of the DataGridView to check whether or not the same value is selected more than once. If it is then a error message is displayed in the row header column.
The combobox in error will not lose focus until the error is resolved.
Private Sub DataGridView1_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating
Dim headerText As String = DataGridView1.Columns(e.ColumnIndex).HeaderText
'Abort validation if cell is not in the Mapping column.
If Not headerText.Equals("Column Mapping") Then Return
'Clear error on current row.
DataGridView1.Rows(e.RowIndex).ErrorText = Nothing
e.Cancel = False
Dim newMappingValue As XmlElement = DirectCast([Enum].Parse(GetType(XmlElement), e.FormattedValue), XmlElement)
' Abort validation if cell value equal XmlElement.None
If newMappingValue.Equals(XmlElement.None) Then Return
For Each dgvRow As DataGridViewRow In DataGridView1.Rows
Dim currentMappingValue As XmlElement = dgvRow.Cells.Item(headerText).Value
If dgvRow.Index <> e.RowIndex Then
If currentMappingValue.Equals(newMappingValue) Then
DataGridView1.Rows(e.RowIndex).ErrorText = "Value already selected, please select a different value."
e.Cancel = True
End If
End If
Next
End Sub

How to adding checked item from checkedlistbox to combobox

I want to adding checked item from checkedlistbox to my combobox, but i have a little problem here. Combobox only show 1 item last checked.
This is my sample code.
If CheckedListBox1.CheckedItems.Count <> 0 Then
For i As Integer = 0 To CheckedListBox1.CheckedItems.Count - 1
cbCheckedItem.Text = CheckedListBox1.CheckedItems(i).ToString
Next i
End If
anyone can help me show all checked item??
thank's for your help...
You aren't adding the items to the combo box, you're only setting its Text property. That's only changing the text currently displayed in the combo box, and only one item can be displayed at a time.
If you want the items to be permanent and selectable, you need to add them to the combo box control's Items collection.
Sample code:
If CheckedListBox1.CheckedItems.Count > 0 Then
For Each checkedItem In CheckedListBox1.CheckedItems
cbCheckedItem.Items.Add(checkedItem.ToString())
Next
End If
Or, better yet, use the AddRange method:
If CheckedListBox1.CheckedItems.Count > 0 Then
Dim checkedItems() As String = CheckedListBox1.CheckedItems.Cast(Of String).ToArray()
cbCheckedItems.Items.AddRange(checkedItems)
End If
Oddly enough the CheckedListBox has a CheckedItems property, which is a collection. As such you can loop through it like you can any other collection, using a For or For Each loop.
then, Each item needs to be added to the Items collection of the ComboBox.
like this sample:
Public Class frmCheckedListBox
Private Sub frmCheckedListBox_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.CheckedListBox1.Items.Clear()
Me.CheckedListBox1.BeginUpdate()
Me.CheckedListBox1.Items.Add("One")
Me.CheckedListBox1.Items.Add("Two")
Me.CheckedListBox1.Items.Add("Three")
Me.CheckedListBox1.Items.Add("Four")
Me.CheckedListBox1.Items.Add("Five")
Me.CheckedListBox1.EndUpdate()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For Each Item As String In Me.CheckedListBox1.CheckedItems
Me.ComboBox1.Items.Add(Item)
Me.ComboBox1.SelectedIndex = 0
Next
End Sub
End Class
As sample code shows, the CheckedItems collection contains the items that are checked, just as the name suggests. It doesn't contain a Boolean value for each an every item to indicate whether it is checked or not. If an item is checked then that item is in the CheckedItems, and if it isn't then it isn't. You simply need to loop through the collection and get every item in it, because it contains all the items that are checked and none that aren't.
in the end you can put :
Me.Combobox1.items.clear()
because when it would click with sample code it would have the one that clicked then on the next click would return the previous one it had clicked and then the new one all compiled in the combobox selection menu
perhaps my answer can help you solve your problems
Combobox doesn't have a multiselect option. so only one item at a time could be selected.

I am trying to assign a value to a gridview cell

how to assign a cell value to a grid view control cell from a string variable(local variable) using VB.net
After the gridview is populated, I would like to insert some data into one of the cells in a row in edit mode.
Create a label in the cell that is being bound, but leave it unbound. Then in the RowDataBound event you can find the label in the cell and populate it with the value you want.
private myString as String = "Some String"
... blah blah code ...
Protected Sub myGridview_RowDataBound(ByVal sender as Object, ByVal e as GridviewRowEventArgs) Handles myGridview.RowDataBound
If e.Row.RowType = RowTypes.DataRow Then
Dim index as Integer = 3 ' Make this the index of your cell
Dim lbl as Label = CType(e.Row.Cells(index).FindControl("myLabelName"), Label)
lbl.Text = myString
End If
End Sub
You can also do this with a literal, panel, etc. The key is to make sure you get the index right and make sure that you use the name provided in the ItemTemplate when using the FindControl method.
myGridView.Rows(x).Cells(y).Text = someValue
you might get an exception though, if this is a bound control.

Gridviews and DropdownLists

Is it possible to change the data source of a dropdown list in a gridview from another dropdown list selected index changed method in the same gridview?
for example I have a dropdown that needs to change its contents depending on what is chosen in the previous cell of the gridview, which is also a dropdown list.
Any Help would be much appreciated
Thanks
Instead of changing the DataSource when the 1st DropDownList.SelectedIndex changes, you could set the DataSource of the 2nd DropDownList when it is being edited.
An example of how this can be achieved can be found here.
In this article, the author hooks to the EditingControlShowing event in order to change the type of the ComboBox. This can be easily modified to change the DataSource instead:
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
' make sure we are editing the 2nd ComboBox:'
Dim comboBoxColumn2 As DataGridViewComboBoxColumn = DataGridView1.Columns(2)
If (DataGridView1.CurrentCellAddress.X = comboBoxColumn2.DisplayIndex) Then
'here you retrieve the value of the 1st ComboBox:'
Dim comboBox1Value As object = DataGridView1.SelectedRow... 'fill with whatever is needed'
Dim cb As ComboBox = e.Control
If (cb IsNot Nothing) Then
cb.DataSource = Nothing 'maybe not needed, I'm not sure
cb.DataSource = 'here, set the data source based on the value of ComboBox1'
End If
End If
End Sub
Here is another way how I would do this, by example: Two columns (Types, Days), if the user drops-down and chooses 'week', a second combo populates with week days, otherwise, weekends.
For the purpose of this example, add a grid (DataGridView1) with two ComboBoxCell columns and let the first column have these items: week, weekend.
This class will be our data source:
Class WeekDataItem
Sub New(ByVal id As Integer, ByVal name As String)
Me.ID = id
Me.Name = name
End Sub
Public Property ID() As Integer
Get
Return _ID
End Get
Set(ByVal value As Integer)
_ID = value
End Set
End Property
Private _ID As Integer
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private _Name As String
End Class
This function will return our data source, based on the key which can be 'week' or 'weekend':
Function getWeekDataSource(ByVal key As String) As List(Of WeekDataItem)
getWeekDataSource = New List(Of WeekDataItem)
If (key = "week") Then
getWeekDataSource.Add(New WeekDataItem(1, "monday"))
getWeekDataSource.Add(New WeekDataItem(2, "tuesday"))
getWeekDataSource.Add(New WeekDataItem(3, "wednesday"))
getWeekDataSource.Add(New WeekDataItem(4, "thrusday"))
getWeekDataSource.Add(New WeekDataItem(5, "friday"))
ElseIf (key = "weekend") Then
getWeekDataSource.Add(New WeekDataItem(6, "caturday"))
getWeekDataSource.Add(New WeekDataItem(7, "sunday"))
End If
End Function
And lastly, this event will fire when the Type combo value changes, and assign the appropriate data source to our days combo:
Private Sub DataGridView1_CellValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
' if the type dropdown value changed
If (e.ColumnIndex = clmTypes.Index) Then
' set the week dropdown data source for the current row
If Not IsNothing(DataGridView1.CurrentRow) Then
' get the combobox cell we want to change
Dim comboCell As DataGridViewComboBoxCell
comboCell = CType(DataGridView1.CurrentRow.Cells(clmDays.Index), DataGridViewComboBoxCell)
' assign it's new data source
comboCell.DataSource = getWeekDataSource(CStr(DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value))
' update the data source members so it displays info properly
comboCell.DisplayMember = "Name"
comboCell.ValueMember = "ID"
End If
End If
End Sub
Note that this event fires after the cell is validated, ie once you tab off the cell.
It is totally possible. How are populating your dropdownlists ? If all the data is dynamic then you will have to rebuild the entire grid everytime you change the dropdownlist selected item.
If I am not wrong , you are trying to apply Filter mechanism. Are you ? Another way I have done in the past is to build my data source for DropDownList from the rows of GridView. Think about the data that you already have on the screen. Once you are in PreRender Function you can bind needed data in your dropdownlist, this way you will cut out load.