Transfer data from one listview to another when data been double click - vb.net

I have 2 ListView setup.
Listview1 need to pass the data to listview2 when any of the data is double click by user.
How can I archive this? I am using vb 2008.
here is the image :

This is crude and simple, but it will give you a starting point. Note that there are any number of ways to approach this problem, and you will want to figure out any validation and such as required by your application. The biggest hurdle appears to be grabbing a reference to the item which is the target of the double click (as important, making sure that if the user double-clicks in an empty area of the ListView Control, that the last selected item is not added by mistake.
Hope this helps:
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.ListView1.FullRowSelect = True
Me.ListView2.FullRowSelect = True
End Sub
Private Sub AddItemToSecondList(ByVal item As ListViewItem)
' NOTE: We separate this part into its own method so that
' items can be added to the second list by other means
' (such as an "Add to Purchase" button)
' ALSO NOTE: Depending on your requirements, you may want to
' add a check in your code here or elsewhere to prevent
' adding an item more than once.
Me.ListView2.Items.Add(item.Clone())
End Sub
Private Sub ListView1_MouseDoubleClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseDoubleClick
' Use the HitTest method to grab a reference to the item which was
' double-clicked. Note that if the user double-clicks in an empty
' area of the list, the HitTestInfo.Item will be Nothing (which is what
' what we would want to happen):
Dim info As ListViewHitTestInfo = Me.ListView1.HitTest(e.X, e.Y)
'Get a reference to the item:
Dim item As ListViewItem = info.Item
' Make sure an item was the trget of the double-click:
If Not item Is Nothing Then
Me.AddItemToSecondList(item)
End If
End Sub
End Class

Related

parse value from datagrid to button name

I'm building a form that has many buttons, all buttons do the same thing: add 1 every time they are clicked. Every pressed button is sent to a datagridview along with the time they are pressed. Datagrid values look like this:
a_1_serv (button name), 18:05:00(time).
Sometimes I want to delete the last row. Everything works fine so far.
When I delete the last row, I want to change the text of the button (a_1_serv).
I can parse the dgv value (a_1_serv) to a variable but I can't bind it to the appropriate button name so I can control it.
Is there a way to do it?
Don't store your program state in your UI
Create a data structure to hold the information, and let the DataGridView be a "view", not treating it as a variable. You will save yourself headaches vs using the UI as a variable.
That said, create a class to represent your information
Public Class Data
Public Sub New(button As Button, time As DateTime)
Me.Button = button
Me.Time = time
End Sub
<System.ComponentModel.Browsable(False)>
Public Property Button As Button
Public ReadOnly Property Text As String
Get
Return Button.Name
End Get
End Property
Public Property Time As DateTime
End Class
And your code can manipulate the data in a variable off the UI. Bind the data to the DataGridView for display.
Private datas As New List(Of Data)()
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click
addButton(DirectCast(sender, Button))
End Sub
Private Sub RemoveLastButton_Click(sender As Object, e As EventArgs) Handles RemoveLastButton.Click
removeLast()
End Sub
Private Sub addButton(b As Button)
datas.Add(New Data(b, DateTime.Now))
bindData()
End Sub
Private Sub removeLast()
Dim b = datas.Last.Button
b.Text = "new text" ' change to whatever
datas.RemoveAt(datas.Count - 1)
bindData()
End Sub
Private Sub bindData()
DataGridView1.DataSource = Nothing
DataGridView1.DataSource = datas
End Sub
This does exactly what you stated but there may be inconsistency in these two bits of information you provided: a_1_serv (button name) and I want to change the text of the button .... This changes the button text but not the name. The name is displayed in the grid. You can change the data class to display the text or whatever. But the point is this approach will keep your data off the UI and you won't need to look up the control by name anymore.

Why Serial number is vanished in DataGridView?

I am generating Auto Serial number in DataGridView using below code:
Public Class Form1
Dim table As New DataTable()
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
table.Columns.Add("Sl", Type.GetType("System.Int32"))
table.Columns.Add("Id", Type.GetType("System.Int32"))
table.Columns.Add("Name", Type.GetType("System.String"))
table.Columns.Add("Amount", Type.GetType("System.Int32"))
DataGridView1.DataSource = table
DataGridView1.Columns(0).ReadOnly = True
DataGridView1.Columns(2).ReadOnly = True
End Sub
Private Sub DgvRowCountChanged()
For Each dgvr As DataGridViewRow In Me.DataGridView1.Rows
dgvr.Cells(0).Value = dgvr.Index + 1
Next
End Sub
Private Sub DataGridView1_RowsAdded(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) Handles DataGridView1.RowsAdded
Me.DgvRowCountChanged()
End Sub
Private Sub DataGridView1_RowsRemoved(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewRowsRemovedEventArgs) Handles DataGridView1.RowsRemoved
Me.DgvRowCountChanged()
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim Index As Integer
If DataGridView1.RowCount > 1 Then
Index = DataGridView1.CurrentCell.RowIndex
DataGridView1.Rows.RemoveAt(Index)
End If
End Sub
End Class
Serial number appears, but when I click on next column it disappears. Why is that happening?
Do this, make life easy:
Ditch all that code
Make a new form
Add a new item of type DataSet to your project, and give it a nice name (not DataSet1)
Double click the dataset, so its design surface appears
Right click the surface, choose "Add new.. DataTable", give it a more imaginative name than DataTable1. I'll assume you choose License (serial number? name? seems licensey)
Right click the new datatable and choose "Add New.. Column"
Name the new column Sl, and use the properties grid to give it a type of System.Int32
Repeat for your other columns
Save
Open the Data Sources window on the View menu (Other Windows item)
Open the new blank form you made in step 2
Expand every node you can see in the Data Sources window
Drag the node representing your datatable (the one with an icon looking like a datagridview next toit) out of the data sources window and drop it on the form
Remove (delete) the bindingnavigator it created (you wont need it)
CLick the datagridview, CLick the small arrow that appeared in the top right of the control to show the popup menu, choose Edit Columns
Make whatever columns you want read only
Set other properties like sizes of columns, fill weights, header texts etc
Open the code of your form. add a single row of data to the datatable, in the constructor, after the initializecomponent() call:
Me.myImaginativeDataSetName.License.AddLicenseRow(1, 1, "Name Blah", 1234)
That's it. It looks like a lot because I've broken it down into the absolute step by step - about the only thing that isn't there is reminding you to take a breath every few steps because you'll be so blown away how easy it makes your life when you get the IDE to write code for you, ;)
OK, it's maybe not that exciting... But you already use the Forms designer to write reams of code for you, so this is how you leverage the other tools so you don't have to work with un-typed datasets all the time. Ugh.
The dataset this creates has a full suite of nicely named properties; don't use the basic stringy stuff ever again:
'yes - do this
For Each ro as LicenseRow in myDataSet.License
If ro.IsNameNull Then ro.Name = "Default Name" & ro.Sl
Next ro
'no - heck no
For Each ro as DataRow in myDataSet.Tables("License").Rows
If ro.IsNull("Naem") Then ro.item("Name") = "Default Name" & Convert.ToInt32(ro.Item("Sl"))
Next ro
See how much cleaner the first one is? ro.Sl is a nice Integer property, no casting or converting, no incessant Tables this or Columns/Rows that, Intellisense helps you out becaise it's all strongly named stuff, no typos in string column names like I made in the second...
It looks like youre trying to prevent the user from adding rows with this:
If DataGridView1.RowCount > 1 Then
Index = DataGridView1.CurrentCell.RowIndex
DataGridView1.Rows.RemoveAt(Index)
End If
End Sub
If so, click the datagridview on the form designer and in the properties grid set AllowUserToAddRows to false. If youre also trying to prevent deletion set the same on AllowUserToDeleteRows

vb.net add values from listbox to textbox via drag&drop AND via double click

I'm struggling with some functionality I want to use on my Windows form.
( Just for info, this is for an AutoDesk Inventor AddIn. )
This is my form layout.
The current workflow
The top 4 list-boxes are filled with available parameter names. The user chooses the parameter(s) he/she wants to use and drags and drops it into one of the driving parameter text-boxes ( marked with the <1> label ).
The code that relates to the drag and drop operations
Private Sub lstTemp_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles lbModelParameters.MouseDown,
lbUserParameters.MouseDown,
lbReferenceParameters.MouseDown,
lbLinkedParameters.MouseDown
' In order to access a specific item in a listbox.itemcollection, you must think of it
' as an array of data or a collection and access it in the same manner by always
' letting VB know which item you intend to use by identifying it with its index location
' within the collection. And this is better than taking up basket weaving :-)
lbModelParameters.DoDragDrop(sender.Items(sender.SelectedIndex()).ToString, DragDropEffects.Move)
End Sub
Private Sub txtTemp_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) _
Handles tbParameter1.DragEnter,
tbParameter2.DragEnter,
tbParameter3.DragEnter,
tbParameter4.DragEnter,
tbParameter5.DragEnter
'Check the format of the incoming data and accept it if the destination control is able to handle
' the data format
'Data verification
If e.Data().GetDataPresent(DataFormats.Text) Then
e.Effect() = DragDropEffects.Move
Else
e.Effect() = DragDropEffects.None
End If
End Sub
Private Sub txtTemp_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) _
Handles tbParameter1.DragDrop,
tbParameter2.DragDrop,
tbParameter3.DragDrop,
tbParameter4.DragDrop,
tbParameter5.DragDrop
'This procedure receives the dragged data once it passes the data verification handled by the DragEnter method
'Drops the data onto the destination control
sender.Text() = e.Data().GetData(DataFormats.Text).ToString()
End Sub
New functionality
Now I would like to decrease the user mouse movement for ergonomic reasons and speed. But I would also like to keep to the drag and drop functionality. As it can overwrite a value that has already been added by the user.
I would like to be able to DoubleClick a item in the listbox, and that item should be added to the first empty textbox. I named my textboxes with a number so it's easy to loop over them all to check if it's empty.
I tried doing it with this code, but my double click event never gets fired. It always goes to the drag and drop. How do you do handle this, that the double click gets fired instead of drag drop?
Private Sub ParameterAddDoubleClick(sender As Object, e As EventArgs) _
Handles lbModelParameters.DoubleClick,
lbUserParameters.DoubleClick,
lbReferenceParameters.DoubleClick,
lbLinkedParameters.DoubleClick
Dim oControl As Windows.Forms.ListBox
oControl = DirectCast(sender, Windows.Forms.ListBox)
' Add line in likedparameters listbox
If oControl.SelectedIndex <> -1 Then
' Loop trough all the controls to see if one is empty
' if it's empty add parameter, else go to next
' if all textboxes are used do nothing.
For i = 1 To 6
Dim oTextbox As Windows.Forms.TextBox =
CType(gbDrivingParameters.Controls("tbParameter" & i),
Windows.Forms.TextBox)
If oTextbox.TextLength = 0 Then
' Add the sender item into the linked listbox
oTextbox.Text = oControl.Items.Item(oControl.SelectedIndex)
End If
Next
End If
End Sub
I hope my question is clear, and well prepared. If there is additional information needed, please let me know in a comment.
Mousedown triggers the DoDragDrop, wich stops the doubleclick-event from firing.
To identify if a user doubleclicks or wants to perform a dragdrop, consider the following:
Private Sub ListBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListBox1.MouseDown
' Determine whether we are performing a drag operation OR a double click
If e.Clicks = 1 Then
TextBox1.Text = "mousedown"
Else
TextBox1.Text = "dblclick"
End If
End Sub

Initialize not properly make with classes vb.net

So, I need to do an program for a client and he wants a search bar in it. So I made it and everything worked perfectly but I put it in my main form. Now, I want to put it in a class but when I initialize the program, it gives me the following error
An error occurred while creating the form. For more information,
see Exception.InnerException. The error is: The form is self-reference during
construction from a default instance, which led to infinite recursion. In the
constructor of the form, refer to the form using 'Me'.
I tried to put Me.Rbtn_X... but it doesn't recognize it.
Initialization
' Main form
Public Sub New()
InitializeComponent()
Initialize_search()
End Sub
Initialize_search()
' Main form
' search is initialize like this :
' Dim search as New Research
Private Sub Initialize_search()
search.generate_autocomplete()
End Sub
generate_autocomplete()
' Research class
Sub generate_autocomplete()
' Main_form = Main form
Dim field = ""
' This is the place where the program fail
If Main_form.RbtnR_avancee_contact.Checked Then
field = "personneressource"
Else
field = "beneficiaire"
End if
' ....
End Sub
Is there something I didn't understand or It's not possible to do it that way?
Edit: added Form_shown event
Public Sub New()
InitializeComponent()
' Initialize_search()
End Sub
Private Sub Form_personne_Shown(sender As Object, e As EventArgs) Handles Me.Shown
MessageBox.Show("You are in the Form.Shown event.")
End Sub
The form is not created (fully) until New completes. By adding your Initialize_search to it, it eventually leads to the statement `Main_form.RbtnR_avancee_contact.Checked'. This is wrong on two counts:
1) the form doesnt exist yet, so you cant refer to it. (this is what the error meant with 'form is self-reference during construction')
2) the ref should be Me.RbtnR (which is what it meant by 'refer to the form using 'Me'')
Move your Initialize_search to the Form_shown event. Your code should look like this (including Lar's suggestion)
' Main form
Public Sub New()
' REQUIRED
InitializeComponent()
End Sub
If there is really something that needs to be setup for this, add it to the form_shown event:
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Shown
' NOTE: even .NET refers to ME not MainForm etc
InitializePanel
InitializeSeach
End Sub
Then:
Private Sub Initialize_search()
search.generate_autocomplete(Me.RbtnR_avancee_contact.Checked)
End Sub
Then:
Sub generate_autocomplete(AdvContact as Boolean)
Dim field AS STRING = ""
If AdvContact Then
field = "personneressource"
Else
field = "beneficiaire"
End if
' ....
End Sub
Your search class doesn't have a reference to the instance of the form's controls.
Try passing the value instead:
Sub generate_autocomplete(advancedChecked As Boolean)
Dim field As String = ""
If advancedChecked Then
field = "personneressource"
Else
field = "beneficiaire"
End if
End Sub
Then when you call it:
search.generate_autocomplete(Me.RbtnR_avancee_contact.Checked)
Even if did work like you want it to, according to your code, it would always result in field containing the same value (whichever was set in designer).
Instead, try putting this code inside RbtnR_avancee_contact.Checked event. Or even TextChanged for the autocomplete box (and initialize it for the first time user enters anything), it would examine the checked state and populate autocomplete items.
With this approach, if your user never uses the search box, you don't need to initialize it.

Edit Update DatagridView VB.Net (No Database)

Good day everyone.
I need your help in this project I am into (a Visual Basic program with no database.) It just contains a Datagridview, a Textbox, and three buttons (an "Add" Button, a "Edit" and an "Update" Button).
1 . Is there any way (like using "for loop") to automatically assign DataGridView1.Item("item location") to the one edited and be updated?
2 . Or is it possible to just click an item in the Datagridview then it will be edited at that without passing it to a Textbox, and to be updated at that.
The DataGridViewCellEventArgs variable (e in the method stub the designer will generate for you) of the double click event of the cell has RowIndex and ColumnIndex properties which refer to the position of the cell you clicked.
Save those (in a class variable possibly or a local one if that's all you need) and then refer to them when you update the cell in your DataGridView, possibly like this MyDataGridView.Item(e.ColumnIndex, e.RowIndex) or MyDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex) where e is the variable from the double click event handler.
For you cell double click event you could have something like this:
Private Sub DataGridView1_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
Using myEditor As New frmCellEditor(Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value)
If myEditor.ShowDialog() = DialogResult.OK Then
Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value = myEditor.NewCellValue
End If
End Using
End Sub
This will call a new instance of your editor and get a value from you. For the purpose of this demo I have made a form like this:
Public Class frmCellEditor
Public NewCellValue As Integer
Public Sub New(ByVal CurrentCellValue As Object)
InitializeComponent()
Me.TextBox1.Text = CStr(CurrentCellValue)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.NewCellValue = CInt(Me.TextBox1.Text)
Me.DialogResult = DialogResult.OK
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Call Me.Close()
End Sub
End Class
Which just has two buttons (Button1 = OK, Button2 = Cancel). When you click OK, it just returns the value 1 which then gets set as the value of the cell.
This is a VERY simplistic example, but it should provide you the basics of what you are trying to do.
UPDATE:
I updated the code for the editor interface so it will include handling for passing the value back and forth from the form with your datagridview.
In your project, make a new form called frmCellEditor. This forms has to have two buttons and a textbox (Make sure that the programmatic names match!). Replace the code with the code listed above. You will have to add Imports System.Windows.Forms above the class as well.
Amend the event handler for the cell double click event of your datagrid to pass the cell value when frmCellEditor is constructed (the line going ... New frmCellEditor(...).
How many columns does your DataGridView has?
Based on how you populate your DataGridView, I'll assume only 1.
Declare this on top of your form
Dim i as Integer
On your btnUpdate_Click Event (Just combine your Edit and Update button into One)
SELECT CASE btnUpdate.Text
Case "Update"
With DataGridView1
'Check if there is a selected row
If .SelectedRows.Count = 0 Then
Msgbox "No Row Selected for Update"
Exit Sub
End If
i = .CurrentRow.Index 'Remember the Row Position
Textbox1.Text = .item(0 ,i).value 'Pass the Value to the textbox
.Enabled = False 'Disable DataGridView to prevent users from clicking other row while updating.
btnUpdate.Text = "Save"
End With
Case Else 'Save
DatagridView1.Item(0,i).Value = Textbox1.Text
btnUpdate.Text = "Update"
END SELECT
Thanks for those who contributed to finding answers for this thread. I have not used your solutions for now (maybe some other time). After some research, I've found an answer for problem 2 (more user friendly at that):
2 . Or is it possible to just click an item in the Datagridview then
it will be edited at that without passing it to a Textbox, and to be
updated at that.
Here's what i did:
in Private Sub Form1_Load, just add:
yourDataGridView.EditMode = DataGridViewEditMode.EditOnEnter
in Private Sub yourDataGridView_(whatever event here: DoubleCellClick, CellContentClick, etc.) add:
DataGridView1(e.ColumnIndex, e.RowIndex).[ReadOnly] = False
DataGridView1.BeginEdit(False)