Custom Textbox Zoom - Return text to active datagridview cell? - vb.net

I have 2 Datagridview controls in same form. Each Datagrid has some columns where user will write long texts, so I designed form with RichTextBox that opens when user double-clicks these columns to enlarge text-entry. Code works, but I want to use same form for both Datagrids, so I should somehow return text to active datagridview cell. Here is my code (for Datagridview1):
TextZoomForm:
Public Class TextZoomForm
Public OpenedForm1 As New Form1
Private Sub RichTextBox1_DoubleClick(sender As Object, e As EventArgs) Handles RichTextBox1.DoubleClick
OpenedForm1.DataGridView1.CurrentCell.Value = RichTextBox1.Text
OpenedForm1.Label24.Focus()
Me.Close()
End Sub
Private Sub TextZoom_Load(sender As Object, e As EventArgs) Handles Me.Load
RichTextBox1.Text = OpenedForm1.DataGridView1.CurrentCell.Value
End Sub
End Class
DataGridView1_CellMouseDoubleClick in Form1:
Private Sub DataGridView1_CellMouseDoubleClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDoubleClick
If e.ColumnIndex = 1 Then
Dim cp = Cursor.Position
cp.Y += CInt(Cursor.Size.Height * (-0.5))
cp.X += CInt(Cursor.Size.Width * 0.8)
Dim f As New TextZoomForm()
f.OpenedForm1 = Me
f.Show()
f.Location = New Point(cp)
End If
End Sub
Any ideas on how to return text to active datagridview cell?

Change your zoomed form so that it doesn't know where its data comes from. Instead the control using it will pass the data.
Public Class TextZoomForm
Public Property ZoomedText As String
Get
Return RichTextBox1.Text
End Get
Set(value As String)
RichTextBox1.Text = value
End Set
End Property
Private Sub RichTextBox1_DoubleClick(sender As Object, e As EventArgs) Handles RichTextBox1.DoubleClick
Me.Close()
End Sub
End Class
To call the form change your code to the following:
Private Sub DataGridView1_CellMouseDoubleClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDoubleClick
...
Dim f As New TextZoomForm()
f.ZoomedText = DataGridView1.CurrentCell.Value
f.ShowDialog()
'Great breakpoint location.
DataGridView1.CurrentCell.Value = f.ZoomedText
Label24.Focus()
....
End Sub
Using ShowDialog prevents the user from changing the current cell part way through your call.
If you need it modeless then you should:
store the cell that the user has selected
handle the FormClosing event.
Test the DialogResult to make sure the user pressed ok
write the data back to the stored cell.

Related

VB: Populate a textbox with popup from txt

I am creating a vb file, and I have a txt file with some that I want to populate a textbox.
What it is currently doing: It is choosing an option that i input in the textbox that I have created.
What I want it to do: Create a popup with every option from a textbox file, show it on screen, let me choose, and then populate another textbox with my choice.
Current code and screenshot:
Public Class Form1
Private Sub TextBox1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseClick
Dim f As New Form2
Try
f.Owner = Me
'
' Before showing the child form populate TextBoxes
'
f.TextBox1.Text = "1"
f.TextBox2.Text = "2"
f.TextBox3.Text = "3"
If f.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim Box = (From T In f.Controls.OfType(Of TextBox)()
Where Not String.IsNullOrWhiteSpace(T.Text)
Select T Order By T.Name).FirstOrDefault
If Box IsNot Nothing Then
Me.TextBox1.Text = Box.Text
End If
End If
Finally
f.Dispose()
End Try
End Sub
End Class
Form 2
Public Class Form2
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim Box = (From T In Controls.OfType(Of TextBox)()
Where Not String.IsNullOrWhiteSpace(T.Text)
Select T Order By T.Name).FirstOrDefault
If Box IsNot Nothing Then
CType(Me.Owner, Form1).TextBox1.Text = Box.Text
End If
CType(Me.Owner, Form1).ActiveControl = CType(Me.Owner, Form1).cmdClose
Close()
End Sub
End Class
Image:
edit: now i only need to make the checkbox into locked textboxes, one line from the text file each.

cmbComboBox.SelectionStart always returns zero irrespective of cursor location

For some reason the "SelectionStart" property behaves differently from TextBox to ComboBox.
Create a TextBox and a ComboBox. Make sure DropDownStyle = DropDown (NOT DropDownList!)
Add these Leave events (same result if you use LostFocus event):
Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave
Debug.Print("Textbox: " & TextBox1.SelectionStart)
End Sub
Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
Debug.Print("ComboBox: " & ComboBox1.SelectionStart)
End Sub
Now type text into each control and change focus from control to control, with the selection cursor in different places in the string.
I get this:
Textbox: 6
ComboBox: 0
Textbox: 8
ComboBox: 0
Textbox: 5
ComboBox: 0
Textbox: 4
ComboBox: 0
... and so on
When the textbox loses focus, it returns the correct SelectionStart.
When the combobox loses focus, it always returns zero.
Is there a reason, solution or reasonable workaround? I cannot seem to intercept this without creating a new variable for each combo control, and storing the SelectionStart on every click and keypress event (assuming the user might click the mouse, use arrow keys or type characters).
I just did some testing and it appears that the selection is reset between the Leave and LostFocus events as well as between the Enter and GotFocus events. I tried remembering the values on the first of each pair and restoring it on the second and it worked as desired:
Private comboBox1SelectionStart As Integer
Private comboBox1SelectionLength As Integer
Private Sub ComboBox1_Enter(sender As Object, e As EventArgs) Handles ComboBox1.Enter
comboBox1SelectionStart = ComboBox1.SelectionStart
comboBox1SelectionLength = ComboBox1.SelectionLength
End Sub
Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
comboBox1SelectionStart = ComboBox1.SelectionStart
comboBox1SelectionLength = ComboBox1.SelectionLength
End Sub
Private Sub ComboBox1_GotFocus(sender As Object, e As EventArgs) Handles ComboBox1.GotFocus
ComboBox1.SelectionStart = comboBox1SelectionStart
ComboBox1.SelectionLength = comboBox1SelectionLength
End Sub
Private Sub ComboBox1_LostFocus(sender As Object, e As EventArgs) Handles ComboBox1.LostFocus
ComboBox1.SelectionStart = comboBox1SelectionStart
ComboBox1.SelectionLength = comboBox1SelectionLength
End Sub
You don't want to have to do that every time for every CokmboBox so you can build it into a custom control and then use that in place of the standard control:
Public Class ComboBoxEx
Inherits ComboBox
Private selectionStartTemp As Integer
Private selectionLengthTemp As Integer
Protected Overrides Sub OnEnter(e As EventArgs)
MyBase.OnEnter(e)
'Remember the current selection.
selectionStartTemp = SelectionStart
selectionLengthTemp = SelectionLength
End Sub
Protected Overrides Sub OnGotFocus(e As EventArgs)
'Restore the selection.
SelectionStart = selectionStartTemp
SelectionLength = selectionLengthTemp
MyBase.OnGotFocus(e)
End Sub
Protected Overrides Sub OnLeave(e As EventArgs)
MyBase.OnLeave(e)
'Remember the current selection.
selectionStartTemp = SelectionStart
selectionLengthTemp = SelectionLength
End Sub
Protected Overrides Sub OnLostFocus(e As EventArgs)
'Restore the selection.
SelectionStart = selectionStartTemp
SelectionLength = selectionLengthTemp
MyBase.OnLostFocus(e)
End Sub
End Class
A side-effect of this is that you will see the text selected even when the control doesn't have focus. The ComboBox has no HideSelection property like the TextBox does. If you don't like this then I'd imagine that you could find a way to make it behave like the TextBox does but that's a different question so I won't go into it here.
I think I've got it, using your idea but just setting the value in a different location.
Dim ComboSelectionStart As Integer
Private Sub cmbComboBox_KeyUp(sender As Object, e As KeyEventArgs) Handles cmbComboBox.KeyUp
'Store selection on any key press
ComboSelectionStart = cmbComboBox.SelectionStart
End Sub
Private Sub cmbComboBox_MouseClick(sender As Object, e As MouseEventArgs) Handles cmbComboBox.MouseClick
'Store selection on any mouse click
ComboSelectionStart = cmbComboBox.SelectionStart
End Sub
Private Sub cmbComboBox_Leave(sender As Object, e As EventArgs) Handles cmbComboBox.Leave
'Returns correct value here because it was not altered by LostFocus event
Debug.Print(ComboSelectionStart .ToString)
End Sub
When you modify the OnLeave() sub in the class provided by #jmcilhinney it actually works nicely.
Protected Overrides Sub OnLeave(e As EventArgs)
'Remember the current selection.
selectionStartTemp = SelectionStart
selectionLengthTemp = SelectionLength
MyBase.OnLeave(e) 'this has to go last because it modifies the SelectionStart...
End Sub

Get combobox selected from another form dynamically

I have a combobox in a form1 and a datagridview in another form2.
I want to get the combobox selected with a value from the datagridview in the second form
I use the code below in form2 and it works:
Private Sub DataGridView1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
form1.CBO_fournisseur.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
Me.Close()
End Sub
But what I want to do is that the name of the form is passed dynamically to avoid using and IFELSE clause to enumerate all the forms I have in my project that use form2
Private Sub DataGridView1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
If formbon2.Name = "FRM_BN_RECEPTION_CUIR" Then
FRM_BN_RECEPTION_CUIR.CBO_fournisseur.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
ElseIf formbon2.Name = "frm_reception_acc_provisoire" Then
frm_reception_acc_provisoire.CBO_1.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
End If
Me.Close()
End Sub
I think I've got what you want to do. I strongly suggest you stop using the Form as a Shared resource.
Use a constructor like this in your Form2:
Private ParentFormCombo as Combobox
Public Sub New(ByVal pCmb as Combobox)
ParentFormCombo = pCmb
End Sub
Then in your doubleclick you just change the text of ParentFormCombo
ParentFormCombo.Text = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString
Then you have to stop using:
FrmList_View.Show()
Now you should always use the constructor instead (New()). So do the following instead:
Dim f As New FrmList_View(CBO_fournisseur)
'or
Dim f As New FrmList_View(CBO_1)
f.Show()

Copying text from one textbox to one on another form and sorting between textboxes

I am still learning on vb.net but I have main form (form1) that has 2 columns. One called Red and the other Yellow. I have a button that opens a form (form2) that has a textbox that allows the user to put in someone's name and a combobox to select a color. What I am trying to accomplish it when they click the submit button on form2, the name will show up in the proper column in form1. Both colors on form1 has their own textbox under it. Red has textbox1 and Yellow has textbox2. Can anyone assist on how I would go about doing this? I am using Visual Studio 2010 VB.Net. Thanks!!
Danny
So many ways to do this...here's another one.
Code in Form1:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim f2 As New Form2
If f2.ShowDialog = Windows.Forms.DialogResult.OK Then
Select Case f2.ComboBox1.SelectedItem.ToString.ToLower
Case "red"
TextBox1.AppendText(f2.TextBox1.Text & Environment.NewLine)
Case "yellow"
TextBox2.AppendText(f2.TextBox1.Text & Environment.NewLine)
Case Else
MessageBox.Show("Unkown Color!")
End Select
End If
End Sub
End Class
and in Form2:
Public Class Form2
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.DialogResult = Windows.Forms.DialogResult.Cancel
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If TextBox1.TextLength > 0 AndAlso ComboBox1.SelectedIndex <> -1 Then
Me.DialogResult = Windows.Forms.DialogResult.OK
End If
End Sub
End Class
From a simple workflow perspective, you can have Form 2 call a method on Form 1 and provides the new name and color. Form 1 would then add the name to the correct column. There are a number of ways to handle this- one would be to have Form 1 instantiate form 2 then pass in a delegate reference for the method that will take the name and color.
So in Form 1 -
Public Sub HandleAdd(name as String, color as String)
' Do Stuff Here.
End Sub
Public Sub AddPlayerButton_Click(sender as Object, e as EventArgs) Handles AddPlayerButton.Click
Dim frm As New Form2
frm.AfterAdd = AddressOf HandleAdd
frm.Show
End Sub
And in Form 2 -
Public Property AfterAdd As Action(of String, String)
Public Sub OKButton_Click(sender as Object, e as EventArgs) Handles OK.Click
If AfterAdd IsNot Nothing Then AfterAdd(playerName.value, playerColor.value)
End Sub
Or something like that.

How to return selected item on listbox on the second form to the main form in visual basic?

So basically you have a main form that shows only a label (lblTotalPrice) and a button that when you click it, it opens a second form that contains a listbox with different prices packages (lstPackages). How do do you select an item from lstPackages that is on the second form and return it to lblTotalPrice, which is located on the main form?
I attempted this code using a function (thought it would be useful for calculations), but it seems like it didn't work:
On my second form, I populated the lstPackages with it's name using parallel arrays:
Dim strPackages As String = {"Package 1", "Package 2", "Package 3", "Package 4", "Package 5"}
Dim decPrice As String = {100D, 200D, 300D, 400D, 500D}
Private Sub SecondForm_Activated(sender As Object, e As EventArgs) Handles MyBase.Activate
Dim frmMain as New
Dim i As Integer
For i = 0 To strPackages.Length - 1
lstPackages.Items.Add(strPackages(i))
Next
End Sub
After I tried to select a value on lstPackages, but I just was not too sure if I was using the right code to select the item and return it to the main form:
Function CalcPackage()
Dim decPackages As Decimal = 0D
If lstPackages.SelectedIndex = -1 Then
MessageBox.Show("Select a package")
Else
For i = 0 To lstPackages.SelectedItem - 1
decPackages = lstPackages.SelectedItem(i)
Next i
End If
Return decPackages
End Function
When I have selected the item in the lstPackages, I tried to send the selected item back to the main form, but ran into a problem here:
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnClose.Click
Dim frmMainForm As New MainForm
Dim decTotal As Decimal
decTotal = CalcPackage()
'I was stuck in this part and wasn't sure how to return it to lblTotalPrice (and also close the second form too)
frmMainForm.lblTotalPrice.Text = decTotal.ToString("c")
frmMainForm.Show()
Me.Close()
End Sub
So yea sorry if my code is weird, but I'm hoping to get help on how to return the value of the item to lblTotalPrice on the main form, thanks guys
Part of your problem is that you are newing up an instance of the main form in the button exit click event handler of the second form, as shown in this code posted:
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnClose.Click
Dim frmMainForm As New MainForm
Dim decTotal As Decimal
decTotal = CalcPackage()
'I was stuck in this part and wasn't sure how to return it to lblTotalPrice (and also close the second form too)
frmMainForm.lblTotalPrice.Text = decTotal.ToString("c")
frmMainForm.Show()
Me.Close()
End Sub
Instead pass an instance of the main form to the second form via its constructor, like this:
Public Class SecondForm Inherits Form
Dim theMainForm As MainForm
Public Sub New(mainForm As MainForm)
theMainForm = mainForm
End Sub
End Class
Now you can reference the lblTotalPrice in the MainForm class via the theMainForm variable, like this:
theMainForm.lblTotalPrice.Text = lstPackages.SelectedItem
The theMainForm.lblTotalPrice.Text should only be updated in response to an item being selected from lstPackages not when the second form is closed; so handle the updating of the main form's label in the SelectedIndexChanged event of lstPackages, like this:
Protected Sub lstPackages_IndexChanged(sender As Object, e As EventArgs)
Dim decTotal As Decimal
decTotal = CalcPackage()
theMainForm.lblTotalPrice.Text = decTotal.ToString("c")
End Sub
All the exit button click event handler should do is to show the main form and close the second form, like this:
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnClose.Click
theMainForm.Show()
Me.Close()
End Sub
Just display SecondForm with ShowDialog(), then retrieve the value with the reference to it that you already have:
Public Class MainForm
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim sf As New SecondForm
If sf.ShowDialog = Windows.Forms.DialogResult.OK Then
lblTotalPrice.Text = sf.TotalPrice
End If
End Sub
End Class
Over in SecondForm:
Public Class SecondForm
Private _TotalPrice As Decimal
Public ReadOnly Property TotalPrice As Decimal
Get
Return _TotalPrice
End Get
End Property
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnClose.Click
If lstPackages.SelectedIndex = -1 Then
MessageBox.Show("Select a package")
Else
_TotalPrice = lstPackages.SelectedItem(0)
Me.DialogResult = Windows.Forms.DialogResult.OK
End If
End Sub
End Class