Two-column list-box with input - vb.net

I'm trying to create a control (for the first time) that pops up and shows the user two columns: The column on the left has labels and the column on the right has empty text boxes for user input.
For example:
---------------------
Ingredient | Quantity
---------------------
Carrots |
---------------------
Apples |
---------------------
Bananas |
And so on. It's important that they are able to scroll together.
I have no idea where to start :/ Should I be looking at tables? listboxes?
I know I can't use textboxes because the number of "ingredients" changes every time the control is called

There is a great deal we don't know about the use-case or (real) data and source. One way to display and edit a varying number of items is the DataGridView. If it is on a modal dialog, it 'pops up':
' form level collection of things
Private Recipe As List(Of RecipeItem)
...
' prepare the data and display:
Recipe = New List(Of RecipeItem)
Recipe.Add(New RecipeItem With {.Ingredient = "Carrot"})
Recipe.Add(New RecipeItem With {.Ingredient = "Apple"})
Recipe.Add(New RecipeItem With {.Ingredient = "Banana"})
Recipe.Add(New RecipeItem With {.Ingredient = "Hemlock"})
...
Dim UmCol As New DataGridViewComboBoxColumn
UmCol.DataPropertyName = "UnitMeasure"
UmCol.DataSource = [Enum].GetValues(GetType(UnitMeasure))
dgvDD.DataSource = Recipe
dgvDD.Columns.Remove("UnitMeasure")
dgvDD.Columns.Add(UmCol)
The DGV will save user edits back to the underlying datasource - the recipe list, in this case.
' elsewhere
For Each item In Recipe
Console.WriteLine(item.ToString)
Next
Result:
2 Each of Carrot
1 Tsp of Apple
1.5 Cup of Banana
3 Bushel of Hemlock
A UserControl with dynamically built TextBox controls will also work, but you likely still need a collection to store the data. If the data comes from a database, the DGV will still work fine, just use a DataTable as the source rather than the Recipe collection.

Related

Matching and Placing Values from Another Table

I'm trying to develop a check box switch on a form that auto-fills a check mark when the correct value is selected.
Item
Group
Category
Keyboard
Medium
Electronics
Laptop
High
Electronics
Mouse Pad
Low
Electronics
Apple
Low
Food
Wine
High
Food
Milk
Medium
Food
Goal:
I have a listbox that allows multiple selection of items, given a certain criteria "Category". The list automatically updates based on the category selected. Once selected, I want to see if the item selected falls under a certain "Group", either low, medium, or high.
Current Code:
' Create Array for multiple selection box
Dim ct As Integer, v, ArrCT()
ReDim ArrCT(ct = 0 To Me.testbutton.ItemsSelected.Count - 1)
For Each v In Me.testbutton.ItemsSelected
ArrCT(ct) = Me.testbutton.ItemData(v)
ct = 1 + ct
Next v
' Load table for matching
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("MasterList")
Dim qmct As Integer, x, NewArr()
ReDim NewArr(qmct = 0 to Me.testbutton.ItemsSelected.Count - 1)
For Each x In Me.testbutton.ItemsSelected
NewArr(qmct) = ArrCT(x)
If NewArr(qmct) = rs![Item] Then
NewArr(qmct) = rs![Group]
End If
qmct = 1 + qmct
Next x
My idea was to create a temporary array which stores the selection, and then have a second for-loop go through the array to match the correct "group".
With the second array, despite triple checking the field name, I get:
Run-time error '3265':
Item not found in this collection.
Item information is loaded in the ArrCT array, and adjusts based on the number of selection.
Is there an easier way to call for a value in the table?
*Note: sample table is not my actual data, that has approximately 20 times more items, category and grouping.

DataGridViewComboboxCell display member not showing up

Goal
A datagridview of SteelTypes has a column that has been bound to a dataview (SteelThicknesses). I can select the data and set it correctly. However I cannot load the same information. My datagridview comboboxcell contains the value and editted formatted text but I cannot set the display member information.
Current problem
I have all of my textbox columns loading correctly except the combobox column. The variable of cbCol is set correctly and the EditedFormattedValue and FormattedValue contain the value I want! However the displayMember does not get replicated into the datagridviewcombobox cell.
I am trying to display a "3" into the Épaisseur (thickness) column via setting its value to a primary key (PK_SteelThickness):
See the results below. Everything except my comboboxcell is populated:
Appreciate the help in advance, this has gotten me crazy :)
You don't set the text. You set the underlying ID. The idea is that you bind the column to a parent table and you bind the grid to a child table that has a foreign key to that parent table. You set the foreign key value in the grid cell and the corresponding text value from the parent table gets displayed.
As an example, let's say that you have a Handedness table like so:
Id Name
1 Right
2 Left
3 Ambidextrous
and you have a Person table like so:
Id Name HandednessId
1 Peter 2
2 Paul 1
3 Mary 3
In your grid you would create a DataGridViewComboBoxColumn and set its DataPropertyName property to "HandednessId". When you then bound your Person table to the grid, the HandednessId column would bind to the combo box column. You would bind your Handedness table to the column and set the DisplayMember and ValueMember to "Name" and "Id" respectively. The grid would then display "Left", "Right" and "Ambidextrous" for "Peter", "Paul" and "Mary" respectively. If you wanted to make Peter ambidextrous, you would set the HandednessId cell Value to 3 and then it would display "Ambidextrous".
See this for more information:
Adding a ComboBox Column to a DataGridView
It seems like you're making a lot of work for yourself here. Datagridcombobox can be used to decode a value simply by having its
DataSource set to something that provides the key/value lookup, for example a SteelThicknesses datatable with two columns Disp and Val and has rows like "Thick",1 "Medium", 2 "Thin", 3,
DisplayMember set to a string of the column name from the lookup table that contains the text to show, for example "Disp",
ValueMember set to the string column name from the lookup that has the value that relates to the text to show, for example "Val" and
DataPropertyName set to the name of the property(column) in the other table that has the value to be decoded (one of the values in the Val column of the lookup table) (for example a Products table with a SteelThicknessID column).
The datagridview is bound to the products datatable, the combo will find e.g. 3 in the steelthicknessid column, it will look 3 up in the Val column of the steelthicknesses table and show the text it finds in the Disp column of that row from steelthickesses.if the user changes the value shown by dropping the combo list and picking Thick, it will work the reverse and take 1 from the Val column and update the products table with the new value 1 for steelthicknessid. If you don't want that, make the column or datagridview read only
For a more involved discussion see my answer in DataGridView Loading From LINQ
This is an odd behavior but I found that changing my loading method calls from the new() to the form Load() made it work...
So I changed my initial code from this:
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
LoadSteelPlates()
LoadPlateQuotes()
End Sub
To this:
Private Sub frmQuotePads_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadSteelPlates()
LoadPlateQuotes()
End Sub
This is the only code that was modified and now it works.

Creating Dynamic DataGridViewComboBoxCells

So here is my situation. I have a DataGridView, which has two columns that I am trying to set up as DataGridViewComboBoxColumns called "Received" and "Backordered".
The point of these combo boxes is to create a drop down menu to select how many items are received/backordered when my company receives a shipment. This program will mainly be run on a touch screen setup with no mouse or keyboard, which is why I am opting to use Combo Boxes as opposed to just asking for general user input.
I am attempting to set up the DataGridView as follows:
'Setup of Combo Box Columns
'shipmentData is the name of the DataGridView
Dim receiveCol As New DataGridViewComboBoxColumn()
receiveCol.HeaderText = "Received"
receiveCol.Name = "Received"
shipmentData.Columns.Add(receiveCol)
Dim backorderCol As New DataGridViewComboBoxColumn()
backorderCol.HeaderText = "Backordered"
backorderCol.Name = "Backordered"
shipmentData.Columns.Add(backorderCol)
The above code is in the New() Sub for when the form is created. I am trying to load the data into the ComboBoxes as follows:
Dim rowNum As Integer = 0
For Each op As OrderPart In OrderData.GetPartList()
If op.AmountOrdered > 0 Then
shipmentData.Rows.Add()
shipmentData.Rows(rowNum).Cells("PartNumber").Value = op.PartNumber
shipmentData.Rows(rowNum).Cells("Description").Value = op.Description
shipmentData.Rows(rowNUm).Cells("Ordered").Value = op.AmountOrdered
For it As Integer = 0 To op.AmountOrdered
CType(shipmentData.Rows(rowNum).Cells("Received"), DataGridViewComboBoxCell).Items.Add(it)
CType(shipmentData.Rows(rowNum).Cells("Backordered"), DataGridViewComboBoxCell).Items.Add(it)
Next
rowNum = rowNum + 1
End If
Next
Now when I run the code, the ComboBoxes are created, and their data is added. However whenever I select a data value from the combo box list, and then try to move to another sell I get the following error:
System.ArgumentException: DataGridViewComboBoxCell value is not valid.
Why am I getting this error, and how do I fix it? I can't seem to figure out what it is I am doing wrong in my code.
Although I don't know why are adding incrementing numbers to your dropbox, but if you intend to do that, change your code to the following:
For it As Integer = 0 To op.AmountOrdered
CType(shipmentData.Rows(rowNum).Cells("Received"), DataGridViewComboBoxCell).Items.Add(it.ToString())
CType(shipmentData.Rows(rowNum).Cells("Backordered"), DataGridViewComboBoxCell).Items.Add(it.ToString())
Next

How to get Access Report textbox to concatenate records from a table when the report is generated from a form?

Essentially this includes 3 components.
First is a form, here the user, via a listbox, chooses multiple names.
For example, they highlight the following names.
Jane
John
Bob
They click a button called "btnGenerate" and these three names get entered as seperate records into a table called "NameCriteria" like this:
ID Name
1 Jane
2 John
3 Bob
Along with this, on-click of the button btnGenerate, a report is generated.
What I cannot seem to get working is that on the report, I hope to get a summary of what was selected on the form. I have a textbox on this report which I am trying to get to generate the following result
Jane, John, Bob
OR if there is only one name highlighted when the btnGenerate is clicked, the textbox will only display
Jane
I cannot seem to get this working. In the report, on the textbox, under the textbox's data/control source, I have entered the following code.
=[Forms]![Report]![lstName]
This just leaves the textbox blank. I have also tried referencing the table "NameCriteria" using
=[Table]![NameCriteria]![Name]
and I return #Error in the textbox.
I'd use something along these lines, using ADO, but its been a long day, so there may be simpler solution.
Public Function CONCAT_SQL(strSQL As String) As String
Dim r As ADODB.Recordset
Dim a As Variant
Set r = New ADODB.Recordset
r.Open strSQL, CurrentProject.Connection, 1
a = Split(r.GetString, Chr(13))
ReDim Preserve a(UBound(a) - 1)
CONCAT_SQL = Join(a, ",")
End Function
Called like so,
me.textbox1.value = CONCAT_SQL("Select [Name] from [NameCriteria]")

Formatting a combo box

I have added a ComboBox to a form, no additional formatting so far. I have a text box that the user enters a number of competitors (value) between 20 and 100 into. I want to populate the ComboBox so that the user can select a competitor from 1 to 100 in the ComboBox. So the user will be able to click the drop-down menu and select a competitor from a list of competitors, for example Competitor 1 to Competitor 100.
Please let me know if you need any extra info.
Try this, explanations included:
yourComboBox.Items.Clear() 'to make sure the ComboBox is empty before populating and to avoid duplicating records
If Val(yourTextbox.Text) > 0 Then 'basic checking
For x = 1 To Val(yourTextbox.Text) 'loop from 1 up to the value you entered into the textbox
yourComboBox.Items.Add(x) 'add the value of x which holds the current loop number/competitor
Next
End If