Datagridview with combobox cannot fill in - vb.net

Have datagridview which contains 4 columns created manually in datagridview creator. 1st, 2nd and 3rd columns are just textbox columns but the last one is marked as comboboxcolumn. On my form i have button, when user clicks it new row is add to datagridview. For first three columns data is filled up from some variables, and the last combobox column should be filled up for user from datasource so he could select his value out of it. The problem is i have problems with this combobox column and so far couldn't fill it in. This is my actual code
Private Sub myButton_Click(sender As Object, e As EventArgs) Handles btnAddMatType.Click
Dim dt as DataTable
dt = New Variation().GetAll() 'returning Ids and Names
Dim cbo = CType(dgvMaterials.Columns(3), DataGridViewComboBoxColumn)
cbo.Items.AddRange(dt.AsEnumerable().Select(Function(s) s.Field(Of String)("Name")).ToArray())
try
Dim rodzajID as String = TreeMaterials.SelectedValue
Dim rodzajName as string = TreeMaterials.SelectedNode.Text
Dim material as string = TreeMaterials.SelectedNode.Parent.Text
dgvMaterials.Rows.Add(material, rodzajName, rodzajID)
End Sub
Tried also this:
Private Sub myButton_Click(sender As Object, e As EventArgs) Handles btnAddMatType.Click
Dim dt as DataTable
dt = New Variation().GetAll() 'returning Ids and Names
Dim cbo = CType(dgvMaterials.Columns(3), DataGridViewComboBoxColumn)
cbo.DataSource = dt
cbo.ValueMember = "Id"
cbo.DisplayMember = "Name"
Dim rodzajID as String = TreeMaterials.SelectedValue
Dim rodzajName as string = TreeMaterials.SelectedNode.Text
Dim material as string = TreeMaterials.SelectedNode.Parent.Text
dgvMaterials.Rows.Add(material, rodzajName, rodzajID)
End Sub
In both cases every time user clicks button row is added to datagrid but last column's combobox is empty. How to solve that?

Try to add this line for asociate your comboBox to the wanted column :
dgvMaterials.Columns.Insert(3, cbo)

Related

Adding item into listview1 and remove if the item has already in the listview1 or replace

I have listview1 with 2 columns. I already have a code for adding items but my problem is when I add again the same item in listview1, it shows duplicates and when I continue to add the same item, the items in listview are increasing with same data.
Example for what I need:
When listview1 has already a data in 1st column = 1 and in 2nd column = A, and I want to add again with a data like these 1st column = 1 and in 2nd column = B. I have 2 solutions and I try to code it but with no luck. My 2 solutions is these:
I just want to update only the data in 2nd column, from "A" to "B" but with the same 1st column data and no additional item will be added into listview like nothing just update/replace it.
OR
Remove the item that will cause duplication and add the same item so there will be no duplicates.
Here's my code for adding item:
Private Sub rbChoiceA_Checked(ByVal sender As Object, ByVal e As EventArgs)
Dim rbA As RadioButton = TryCast(sender, RadioButton)
Dim str As String = rbA.Parent.Name
str = str.Remove(0, 6)
lab1.Text = str
Dim item As ListViewItem
Dim row As String() = New String(2) {}
row(0) = str
row(1) = rbA.Text
item = New ListViewItem(row)
ListView1.Items.Add(item)
End Sub
I just need help to add the code for my problem. Your answers is highly appreciated. Thanks in advance!
Find the item before add it
If (ListView1.FindItemWithText(row(0)) Is Nothing) Then
ListView1.Items.Add(item)
End If
I just figured it out because of others help also.I created a function as Dictionary.This code is updating the subitem without adding or deleting item.
Dim thisDict As New Dictionary(Of String, String)
Public Sub listviewupdate(ByVal D As Dictionary(Of String, String))
ListView1.Items.Clear()
For Each KVP As KeyValuePair(Of String, String) In D
Dim LVI As New ListViewItem(KVP.Key)
LVI.SubItems.Add(KVP.Value)
ListView1.Items.Add(LVI)
Next
End Sub
Private Sub rbChoiceA_Checked(ByVal sender As Object, ByVal e As EventArgs)
Dim rbA As RadioButton = TryCast(sender, RadioButton)
Dim str As String = rbA.Parent.Name.Remove(0, 6)
lblItemNo.Text = str
If thisDict.ContainsKey(str) Then thisDict.Remove(str)
thisDict.Add(str, rbA.Text)
listviewupdate(thisDict)
End Sub

Compare the values of two listboxes and add the non-equivalent values to a third listbox

My knowledge of programming is not too extensive but I have just finished my second year of higher education in computer engineering and have taken a few low level programming courses.
In Visual Basic, I am having trouble comparing the values of two ListBox controls and putting the values that aren't the same into another ListBox.
I need to compare the items of ListBox2 to the items of ListBox1 and if there are any items in ListBox2 that are not in ListBox1, add them to ListBox3. I do not need to find the items in ListBox1 that are not in ListBox2. I cannot use a loop to compare their values based on index because these lists are of names which will be constantly added to and removed from. I also cannot sort these ListBoxes.
There was an example for C# that I found here that used LINQ (I don't really know what that is) to compare the lists and then add the result to a TextBox control. However, I need to know how to add them to a ListBox and not a TextBox.
[EDIT] The example that I have tried is this:
Dim result As List(Of String) = (From s1 As String In Me.ListBox1.Items Where Not Me.ListBox2.Items.Contains(s1) Select s1).ToList()
Me.TextBox1.Text = String.Join(Environment.NewLine, result)
Dim one As ListBox = New ListBox()
Dim two As ListBox = New ListBox()
Dim three As ListBox = New ListBox()
Dim unique As Boolean = True
For i As Integer = 0 To one.Items.Count
For j As Integer = 0 To two.Items.Count
If (one.Text = two.Text) Then
unique = False
Else
two.SelectedIndex = j
End If
Next
If (unique) Then
three.Items.Add(one.Text)
Else
one.SelectedIndex = i
unique = True
End If
Next
I believe this may be what you're looking for. What it does is compares each value in Listbox one to all values in Listbox two and if a value is seen to be a duplicate the Boolean flag unique is switched to false and the item is not added to Listbox three.
I think i found the solution:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListBox3.Items.Clear()
Dim result As List(Of String) = (From s1 As String In Me.ListBox2.Items Where Not Me.ListBox1.Items.Contains(s1) Select s1).ToList()
For Each l In result
ListBox3.Items.Add(l)
Next
End Sub
or
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim result As List(Of String) = (From s1 As String In Me.ListBox2.Items Where Not Me.ListBox1.Items.Contains(s1) Select s1).ToList()
For Each l In result
If Not ListBox3.Items.Contains(l) Then
ListBox3.Items.Add(l)
End If
Next
End Sub
Try which works best for you :)

DataGridView is not showing first row after removing other rows

I am having a problem that I have been debugging for some days.
Some context, I have an application where I store the data (in the following code a list of class Expediente) in xml files using serialization. For displaying the data I deserialize it and then I create a datatable which I use as the datasource for the datagrid. I added a datagridcheckbox column to check the ones to delete.
In the datagrid I have a toolstrip button that when clicked it removes the checked -or checked in edit mode thus the line CType(dgvr.Cells(0).GetEditedFormattedValue(dgvr.Index, DataGridViewDataErrorContexts.Commit), Boolean) = True- elements from the datasource and persists the datasource to an xml.
The problem is that when deserializing the xml and loading it again to a datatable and binding the datagrid datasource to it, it removes the first row. If I close the application and open it, the first row appears.
I have debuged and in the datatable the correct numbers of rows appear. Moreover, I have narrowed the problem to the binding navigator, when it sets its binding source to the datable there the first row of the datagrid disappears.
I paste a simplified version of the code, I can provide more if needed.
Note that if in LoadGridExpedientes() I comment the lines
navExpedientes.BindingSource = Nothing
navExpedientes.BindingSource = bs
The first row doesn't disappear but obviously the counter of the binding navigator does not update.
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim chk As New DataGridViewCheckBoxColumn()
grdExpedientes.Columns.Add(chk)
chk.HeaderText = ""
chk.Name = "chk"
'fills a datatable from an xml, it works ok, it fills it with the correct amount of rows
Dim dt As DataTable = Sistema.getInstance.getDataExpedienteForGrid()
Dim bs As New BindingSource
bs.DataSource = dt
grdExpedientes.DataSource = bs
navExpedientes.BindingSource = bs
For i As Integer = 0 To grdExpedientes.Rows.Count - 2
grdExpedientes.Rows(i).Cells(0).Value = True
Next
End Sub
Private Sub LoadGridExpedientes()
grdExpedientes.DataSource = Nothing
navExpedientes.BindingSource = Nothing
grdExpedientes.Columns.Clear()
grdExpedientes.Rows.Clear()
'This is to know if there is already the checkbox column
If Not (grdExpedientes.Columns.Count > 0 AndAlso grdExpedientes.Columns(0).Name = "chk") Then
Dim chk As New DataGridViewCheckBoxColumn()
grdExpedientes.Columns.Add(chk)
chk.HeaderText = ""
chk.Name = "chk"
End If
Dim dt As DataTable = Sistema.getInstance.getDataExpedienteForGrid()
Dim bs As New BindingSource
bs.DataSource = dt
grdExpedientes.DataSource = bs
navExpedientes.BindingSource = bs
End Sub
Private Sub navExpedientesDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles navExpedientesDelete.Click
For i As Integer = 0 To grdExpedientes.Rows.Count - 2
Dim dgvr As DataGridViewRow = grdExpedientes.Rows(i)
If CType(dgvr.Cells(0).Value, Boolean) = True Or _
CType(dgvr.Cells(0).GetEditedFormattedValue(dgvr.Index, DataGridViewDataErrorContexts.Commit), Boolean) = True Then
Dim draux As DataGridViewRow = dgvr
Dim expABorrar As Expediente = CType((From elem As Expediente In Sistema.listExpedientes
Where elem.Expediente = CType(draux.Cells("Expediente (Ficha)").Value, String)
Select elem).FirstOrDefault, Expediente)
Sistema.listExpedientes.Remove(expABorrar)
End If
Next
If System.IO.File.Exists(Sistema.pathListExpedientes) Then
System.IO.File.Delete(Sistema.pathListExpedientes)
End If
Dim sw As System.IO.TextWriter = New System.IO.StreamWriter(Sistema.rutaListaExpedientes, 0)
Serializer(Of Expediente).Serialize(Sistema.listExpedientes, sw, New List(Of Type) From {GetType(Movimiento)})
sw.Close()
LoadGridExpedientes()
End Sub
The problem was that I was using the delete toolstrip button that comes with the binding navigator, it seems that when clicked it has 'embedded' that it deletes the row that was selected that by default is the first one.
I created a new toolstrip button in the binding navigator and the problem was solved. I do not know why not updating the binding navigator binding source also avoided the first row from being removed.

How to Delete selected row in gridview in vb.net by clicking on delete button

This code below was to delete first row and not selected row.
Protected Sub LinkBtn_Del_Click(sender As Object, e As EventArgs)
Dim intpartID As Integer = gvParticipant.DataKeys(0).Value
Dim comPart As New SqlCommand("usp_Participant_Delete", consql)
comPart.CommandType = CommandType.StoredProcedure
comPart.Parameters.Add("#ParID", SqlDbType.Int).Value = intpartID
consql.Open()
comPart.ExecuteNonQuery()
consql.Close()
selectParticipant()
MultiViewall.SetActiveView(viewDisplayWorkshop)
End Sub
Instead of passing 0 when calling the DataKeys() method, you should get the selected index of your GridView. In your case, simply use gvParticipant.SelectedIndex
GridView.SelectedIndex Property

Cannot get the text of multiple selected items in a VB.NET ListBox because it's of type "datarowview"

I've got listbox1 in VB 2010, which is bound to a data source and displays values from a dataset. I bound it using the Designer - i.e. not via the code. I just selected the datasource in the properties of listbox1.
Now I want to retrieve the selected values. When I leave the listbox as single select, then ListBox1.SelectedValue.ToString does the job - it gives me the text of the selected item.
But I need it to allow multiple selections.
This is my code:
Dim items As ListBox.SelectedObjectCollection
items = ListBox1.SelectedItems
For Each i As String In items
MsgBox(i)
Next
And this is the error I get:
Conversion from type 'DataRowView' to type 'String' is not valid.
I've tried a few different ways to get the values of the selected items but there doesn't seem to be any straightforward way to do it. Is it impossible? Is it necessary to declare a new dataset and fill the listbox programmatically or something?
For Each drv As DataRowView In ListBox1.SelectedItems
MessageBox.Show(drv.Item(0).ToString)
Next
Off the top of my head I think you can do:
Dim items As ListBox.SelectedObjectCollection
items = ListBox1.SelectedItems
For Each i As ListViewItem In items
MsgBox(i.Value.ToString())
Next
Check out my question and answer. It allows you to break out the individual entries from a Database into list boxes.
Add 2 List Boxes and a text box to a form then copy this code, You will have to substitute your own Server and database etc entries.
Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Collections
Imports System.Data.SqlClient
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' get the data
Dim SQLConnectionString As String = "Data Source=HL605\RIVWARE;Database=RIVWARE;Integrated Security=true;"
Dim mySQLConnection As New SqlConnection(SQLConnectionString)
' Populate the list box using an array as DataSource.
mySQLConnection.Open()
Dim SQLDataTable As New System.Data.DataTable
'Create new DataAdapter
Dim mySQLDataAdapter = New SqlDataAdapter("SELECT * FROM [Rivware].[dbo].[RivetTypes]", mySQLConnection)
mySQLDataAdapter.Fill(SQLDataTable)
ListBox1.DataSource = SQLDataTable
ListBox1.DisplayMember = "RivetType"
' remove validation data from list
Dim Count As Integer
Dim X As Integer
'get the column of data to search for
For Count = 0 To ListBox1.DataSource.Columns.Count - 1
X = InStr(ListBox1.DataSource.Columns.Item(Count).ToString, "Name")
If X <> 0 Then Exit For
Next
' now search for any invalid rows, in that column. those containing "---"
Dim TheTable As DataTable = CType(ListBox1.DataSource, DataTable)
Dim theRow As DataRow() = TheTable.Select()
Dim RowNumber As Integer
For RowNumber = 0 To UBound(theRow) - 1
If theRow(RowNumber).Item(Count).ToString <> "---" Then
' data is OK so transer it to the other listbox
ListBox2.Items.Add(theRow(RowNumber).Item(Count - 1).ToString)
End If
Next
ListBox2.ClearSelected()
End Sub 'NewNew
Private Sub ListBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox2.SelectedIndexChanged
TextBox1.Text = ListBox2.SelectedItem.ToString()
End Sub
End Class 'ListBoxSample3