drag and drop to tablelayoutpanel from listview - vb.net

I am trying to build a control which implements a tablelayoutpanel for the design and placement of other controls within the control - I need to add functionality which will allow the tablelayoutpanel to accept content from a listview (It does not even need to process it in any fashion at this point) - I, however, can not get the tablelayout panel to even display that it will accept data - only displays the circle/slash symbol. These are kept in 2 separate child mdi forms within the same parent.
currently I have in my listview form
Private Sub Jboard_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.AllowDrop = True
ListView2.AllowDrop = True
end sub
Private Sub ListView2_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragOver, ListView2.DragOver
If e.Data.GetDataPresent(GetType(ListViewItem)) Then
e.Effect = DragDropEffects.All
End If
End Sub
Private Sub ListView2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListView2.MouseDown
Dim item As ListViewItem = ListView2.HitTest(e.Location).Item
If item IsNot Nothing Then
ListView2.DoDragDrop(item, DragDropEffects.All)
End If
End Sub
on my new tablelayoutpanel control form I have
Me.AllowDrop = True
DboardScheduler1.AllowDrop = True
'dboardscheduler1 is my new control
in the code for the control I have
tablelayoutpanel1.AllowDrop = true
What am I missing?

It looks like you only coded the one side, you also need to tell the TLP(like) control how/what to do. Something like this (not sure of the constraints you want, like JUST LVs and only MOVE).
' NOT mousedown
Private Sub ItemDrag(sender As Object, e As ItemDragEventArgs) Handles ...
If e.Button <> Windows.Forms.MouseButtons.Left Then Exit Sub
' ToDo: Decide what to do with multiples. Singles only assumed
' add the item under the cusor as the first, effect as Move
DoDragDrop(e.Item, DragDropEffects.Move)
End Sub
LV Drag OVer:
' probably:
e.Effect = DragDropEffects.None
' because you cant really drop it here, but the No Action shows that it knows
' a D-D is happening.
TLP Drag OVer:
If (e.Data.GetDataPresent(GetType(ListViewItem)) = False) Then
e.Effect = DragDropEffects.None
Exit Sub
Else
e.Effect = DragDropEffects.Move ' or link maybe
End If
TLP DragDrop:
Dim dragLVI As ListViewItem
' get text and do whatever with it
If (e.Data.GetDataPresent(GetType(ListViewItem)) = False) Then
e.Effect = DragDropEffects.None
Exit Sub
Else
dragLVI = CType(e.Data.GetData(GetType(ListViewItem)), _
ListViewItem)
newTextThing = dragLVI.SubItems(0).Text
End If
Something along those lines. The point is that you have to write code for the piece being dropped on.

Related

VB.NET Trigger Datagridview Cell Click on Button CLick

I'm trying to trigger this command when the button is clicked
Private Sub ClickDataGridview(sender As Object, e As DataGridViewCellMouseEventArgs)
If e.RowIndex >= 0 Then
Dim row As DataGridViewRow = DataGridView1.Rows(e.RowIndex)
TextBox1.Text = row.Cells(0).Value.ToString
TextBox2.Text = row.Cells(1).Value.ToString
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
ClickDataGridview()
End Sub
but sadly I received two error
Argument not specified for parameter 'sender' of 'Private Sub ClickDataGridview(sender As Object, e As DataGridViewCellMouseEventArgs)'.
Argument not specified for parameter 'e' of 'Private Sub ClickDataGridview(sender As Object, e As DataGridViewCellMouseEventArgs)'
Should I make it an if statement to work? or should I try something else to trigger this event
There is a way but you have to careful about selection of cells . If you have to do only row operations then it is ok with this. I recommend don't do this instead that put button in gridview for each row and perform operation
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Try
If DataGridView1.SelectedCells.Count > 0 Then
'Here you can change Datagridview row selection property and get selectedrows instead of selected cells
Dim i_rowindex As Integer = DataGridView1.SelectedCells(0).RowIndex
Dim i_colIndex As Integer = DataGridView1.SelectedCells(0).ColumnIndex
DataGridView1_CellMouseClick(sender, New DataGridViewCellMouseEventArgs(i_colIndex, i_rowindex, 0, 0, New MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0)))
End
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
As I may have mentioned once or twice, don't call event handlers directly. Put the common code in it's own method and then call that method from each event handler as appropriate. In this case:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
GetRowValues(DataGridView1.CurrentRow)
End Sub
Private Sub DataGridView1_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseClick
If e.Button = MouseButtons.Left AndAlso e.RowIndex >= 0 Then
GetRowValues(DataGridView1.Rows(e.RowIndex))
End If
End Sub
Private Sub GetRowValues(row As DataGridViewRow)
TextBox1.Text = row.Cells(0).Value.ToString()
TextBox2.Text = row.Cells(1).Value.ToString()
End Sub
I may be missing something, however… I do not understand why you would want to force the user to “click” a button to set the text boxes. If you wire up the grids “SelectionChanged” event and update the text boxes in that event, then the user neither has to click on a button or a cell. If the user uses the Arrow keys, Enter key, Tab key or even “clicks” a cell, the text boxes will change automatically without the user having to click a button.
Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) Handles DataGridView1.SelectionChanged
If (DataGridView1.CurrentRow IsNot Nothing) Then
TextBox1.Text = DataGridView1.CurrentRow.Cells(0).Value.ToString()
TextBox2.Text = DataGridView1.CurrentRow.Cells(1).Value.ToString
End If
End Sub
Or... better yet... if the grid uses a data source, then "Binding" the text boxes to that "same" data source is all that is needed. You will not have to wire up any grid events.
TextBox1.DataBindings.Add(New Binding("Text", datasource, "datasourceColumnName1"))
TextBox2.DataBindings.Add(New Binding("Text", datasource, "datasourceColumnName2"))

How can I change one label out of many by right clicking one of them

I have some simple code. It changes the BorderStyle property of a Label by right-clicking. Nothing fancy, but still. However, I have twenty labels. Is there a simpler way of doing this instead of "copy-paste" this code 20 times?
Private Sub Label1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles Label1.MouseDown
If e.Button = MouseButtons.Right Then
If Label1.BorderStyle = BorderStyle.None Then
Label1.BorderStyle = BorderStyle.FixedSingle
Else
Label1.BorderStyle = BorderStyle.None
End If
End If
End Sub
Private Sub Label2_MouseDown...
...
End Sub
You could either create a custom control which inherits from Label and has the behaviour you want, or you could write a handler which works out which control it is responding to from the sender parameter.
The latter, presented first here, is simpler for a one-off, but the former would be more re-usable, and you wouldn't have to maintain the list of Labels for the AddHandler.
Sub Label_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim lbl = DirectCast(sender, Label)
If e.Button = MouseButtons.Right Then
If lbl.BorderStyle = BorderStyle.None Then
lbl.BorderStyle = BorderStyle.FixedSingle
Else
lbl.BorderStyle = BorderStyle.None
End If
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each l In {Label1, Label2}
AddHandler l.MouseDown, AddressOf Label_MouseDown
Next
End Sub
The AddHandler line connects the MouseDown event of each of the Labels to the specified event handler. (You can add more than one event handler to an event, if needed.)
For a control (your very own custom one) derived from an existing control (a System.Windows.Forms.Label in this case), let's call it BorderedControl, you can follow the instructions at How to: Inherit from Existing Windows Forms Controls (it's too close to plagiarism to copy it to here), and then your code for the control might look like:
Public Class BorderedLabel
Inherits Label
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
If e.Button = MouseButtons.Right Then
If Me.BorderStyle = BorderStyle.None Then
Me.BorderStyle = BorderStyle.FixedSingle
Else
Me.BorderStyle = BorderStyle.None
End If
End If
MyBase.OnMouseDown(e)
End Sub
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
End Class
After you have built your project after adding that code, you will find a new control, named "BorderedLabel", in the ToolBox. You can drag that onto the form "design surface" and it will behave just like an ordinary Label except that it will have your BorderStyle-changing code incorporated automatically.

Adding context_menu items dinamically with custom functions

I create context menu dinamically and want to assign menuitems to my own functions (with arguments). Unfortunatelly that dont go as I would like.
Following example illustrates what I would like to do.
Private Sub dgv_sub_CellMouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgv_sub.CellMouseUp
If e.Button = Windows.Forms.MouseButtons.Right Then
dgv_sub.Rows(e.RowIndex).Selected = True
context_sub.Items.Clear()
context_sub.Items.Add("Delete row " + dgv_sub.CurrentRow.Index.ToString, Nothing) AddressOf delRow(dgv_sub.CurrentRow.Index))
context_sub.Items.Add("Delete all rows", Nothing) , AddressOf delRow(-1))
context_sub.Show(New Point(Cursor.Position.X, Cursor.Position.Y))
End If
End Sub
Private Sub delRow(ByVal rowtodelete As Integer)
End Sub
How to make this properly and get it to work as described?
This is how I usually do these kind of things:
Have a pre populated ContextMenu
Assign the ContextMenu to my DataGridView
Add Events on every ToolStripMenuItem
In each event, first I do a check to make sure that a row has been selected
If dgv_sub.SelectedRows.Count > 0 Then
then, I get the correct row by using the
SelectedRows(0)
To make things neater, you can also use the DataGridView.MouseDown event to make sure that when the user right click a row, it gets selected.
Private Sub dgv_sub_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgv_sub.MouseDown
If e.Button = Windows.Forms.MouseButtons.Right Then
Dim hitTest As DataGridView.HitTestInfo
hitTest = dgv_sub.HitTest(e.X, e.Y)
If hitTest IsNot Nothing AndAlso hitTest.RowIndex > -1 Then
dgv_sub.CurrentCell = dgv_sub.Item(hitTest.ColumnIndex, hitTest.RowIndex)
dgv_sub.Rows(hitTest.RowIndex).Selected = True
End If
End If
End Sub
As you need context items to be dynamic, you will have to do these in the MouseDown event aswell.
In order to add an item properly you still need a normal click event:
context_sub.Items.Add("Name of Item", Nothing, AddressOf item_Click)
Then add a Sub like this:
Private Sub item_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
'Add any logic here, you can still use the dgv_sub.SelectedRows here
End Sub
Ideally you create a different Sub for every context menu item you need to add

Drop onto FlowLayoutPanel

Hi guys Hope all is well
I am wondering(struggling) the following:
I have 5 flowLayoutPanels and 5 PictureBoxes i want to be able to move anyone of the picture boxes over anyone the FLP at run time and have the layout panel add it to FLP.controls.Add()....
I've been at it for Hours and now ill swallow my pride -
I have done the following To get it working, but here i have to manually specify which PixBox intersects with which FLP and i dont want 25 if statements
Private Sub cpbPic1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cpbPic1.MouseUp
If (flpDock1.HasChildren = False) Then 'Test to see if panel is filled
If CBool(CustomPictureBox.IntersectingObjects(cpbPic1, flpDock1)) Then
flpDock1.Controls.Add(cpbPic1) 'Add Pic to Panel
End If
End Sub
cpb: CustomPictureBox
you could always do this:
Private Sub cpbPic1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cpbPic1.MouseUp, cpbPic2.MouseUp, cpbPic3.MouseUp,cpbPic4.MouseUp,cpbPic5.MouseUp
If Not flpDock1.HasChildren Then 'Test to see if panel is filled
If CBool(CustomPictureBox.IntersectingObjects(TryCast(sender,CustomPictureBox), flpDock1)) Then
flpDock1.Controls.Add(TryCast(sender,CustomPictureBox)) 'Add Pic to Panel
End If
End Sub
This will reduce the amount of code you'll have to write significantly, you can further reduce this amount if you think about how to utilize the fact that the event handler passes the Object which raises the flag, like I did here.
Also you can use arbitrary big amount (i think) of objects in a handler as long as they raise the same event
well this can be a work around for what you want to do.
you also have to enable allowdrop to the flowpanels
Private Function FindControl(ByVal ControlName As String, ByVal CurrentControl As Control) As Control
' get the control you need
Dim ctr As Control
For Each ctr In CurrentControl.Controls
If ctr.Name = ControlName Then
Return ctr
Else
ctr = FindControl(ControlName, ctr)
If Not ctr Is Nothing Then
Return ctr
End If
End If
Next ctr
End Function
Private Sub me_DragEnter(sender As Object, e As DragEventArgs) Handles FLP1.DragEnter,FLP2.DragEnter,FLP3.DragEnter
' call the copy effect
If (e.Data.GetDataPresent(DataFormats.Text)) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Sub me_DragDrop(sender As Object, e As DragEventArgs) Handles FLP1.DragDrop,FLP2.DragDrop,FLP3.DragDrop
' get the FLp you're gonna drop the control onto
Dim c As control =FindControl(e.Data.GetData(DataFormats.Text), me)
sender.Controls.Add(c)
end sub
Private Sub Pictureboxs_MouseDown(sender As Object, e As MouseEventArgs) Handles Label1.MouseDown, PB.MouseDown
sender.DoDragDrop(sender.Name, DragDropEffects.Copy)
End Sub
hope that this helps you :) (sorry for my bad english)

vb.net how to handle text dragged onto a button to open a new form with the dragged text directly copied to the richtextbox on the new form?

I want to achieve the following:
The user drags text from any open window not related to my application ( like firefox or word, for example) onto button1 on form1 in my application. when he/she does that, a new form (called form2 that contains a richtextbox) will open and the dragged text is directly copied (or inserted) into the richtextbox of the new form. button1 has allowdrop set to true. Beyond that I don't know how to proceed.
I tried:
e.effects = DragDropEffects.Copy
But it seems it is not enough. Could you help please?
Thanks
Learning about Drag and Drop would be the first step. http://www.vb-helper.com/howto_net_drag_drop.html -or- http://msdn.microsoft.com/en-us/library/aa289508%28VS.71%29.aspx.
Essentially, you need to enable the drag and drop for the target, handle the drag and drop events, and then implement your desired action.
From MSDN regarding Dragging Text:
Private MouseIsDown As Boolean = False
Private Sub TextBox1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseDown
' Set a flag to show that the mouse is down.
MouseIsDown = True
End Sub
Private Sub TextBox1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseMove
If MouseIsDown Then
' Initiate dragging.
TextBox1.DoDragDrop(TextBox1.Text, DragDropEffects.Copy)
End If
MouseIsDown = False
End Sub
Private Sub TextBox2_DragEnter(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles TextBox2.DragEnter
' Check the format of the data being dropped.
If (e.Data.GetDataPresent(DataFormats.Text)) Then
' Display the copy cursor.
e.Effect = DragDropEffects.Copy
Else
' Display the no-drop cursor.
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub TextBox2_DragDrop(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles TextBox2.DragDrop
' Paste the text.
TextBox2.Text = e.Data.GetData(DataFormats.Text)
End Sub
I figured it out. I'm sharing so others might benefit.
First, I declared a global variable in one of the modules:
Public draggedText As String = ""
Second, I handled the dragdrop event on the button as follows:
Private Sub button1_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles button1.DragDrop
draggedText = e.Data.GetData(DataFormats.Text)
frm_form2.Show()
End Sub
Third, in the load event of frm_form2 I added the following:
If draggedText <> "" Then
richTextBox1.Text = draggedText
draggedText = ""
End If
That's it. Not as complicated as I thought. Also, you can add the code for the dragEnter event mentioned in the previous answer to change how the cursor looks.
I hope this helps.