Selecting items in a listbox with drawmode set to ownerdrawfixed - vb.net

I have a listbox which I wanted some items to be a different color, and I understand to do this I have to set the drawmode to ownerdrawfixed. This works fine, but, now I can't retrieve a selected item. With the drawmode set to normal, when I click on an item in the listbox, I have it put that text into a textbox. With the drawmode set to ownerdrawfixed, when I click on an item, I get an error that "conversion from type 'item' to type 'string' is not valid. Also, the listbox is no longer sorted, even tho the sorted property is set to true (when in ownerdrawfixed mode).
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim ac As Integer
LstAll.DrawMode = DrawMode.OwnerDrawFixed
MaxRec = 708
ChkShow = True
FileOpen(1, "C:\MyMov3\MovData.mdt", OpenMode.Random, , , Len(Mv3Rec))
For x = 1 To MaxRec
FileGet(1, Mv3Rec, x + 1)
'This If loop for the colored text
If Mv3Rec.Rc3Mlti = True And ChkShwMlti.Checked = True Then
ac = Asc(Trim(Mv3Rec.Rc3MTitle))
If ac > 0 Then
Dim i As New Item()
i.ItmColor = Color.Red
i.Txt = Trim(Mv3Rec.Rc3MTitle)
LstAll.Items.Add(i)
End If
End If
If ChkShow = True Then
Dim i As New Item() 'Needed for the black text when in ownerdrawfixed mode
i.ItmColor = Color.Black 'Needed for the black text when in ownerdrawfixed mode
i.Txt = Trim(Mv3Rec.Rc3Title) 'Needed for the black text when in ownerdrawfixed mode
LstAll.Items.Add(i) 'Needed for the black text when in ownerdrawfixed mode
'LstAll.Items.Add(Trim(Mv3Rec.Rc3Title)) 'This line adds the text when in normal mode
End If
Next
FileClose(1)
End Sub
Private Sub LstAll_DrawItem(sender As Object, e As System.Windows.Forms.DrawItemEventArgs) Handles LstAll.DrawItem
If e.Index < 0 Then Return
Dim i As Item
i = TryCast(LstAll.Items(e.Index), Item)
If i IsNot Nothing Then
e.Graphics.DrawString(i.Txt, e.Font, New SolidBrush(i.ItmColor), e.Bounds)
End If
End Sub
Private Sub LstAll_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles LstAll.SelectedIndexChanged
TextBox1.Text = LstAll.SelectedItem
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
End
End Sub
End Class
Public Class Item
Public Txt As String
Public ItmColor As Color
End Class
This code is only the essential parts.... and was tested in a new project on a blank form. With a Listbox (renamed to LstAll) A textbox, a checkbox (renamed to ChkShwMlti). This gives the same error as in the program that I need it to work in. It does however use a file that I did not include the Structure for... but I think you can get the idea.

I have figured out this problem. In the LstAll.SelectedIndexChanged
Private Sub LstAll_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles LstAll.SelectedIndexChanged
Dim i As New Item
i = LstAll.SelectedItem
TextBox1.Text = i.Txt
End Sub
this worked as needed.

Related

VB fires changetext event before control is loaded

I need to add some controls to a Visual Basic 2017 form programmatically. One of the controls is a textbox that needs a changetext event handler. Below is some code that accomplishes that task.
HOWEVER, the changetext event handler seems to fire right away, before the form even loads... before the textbox itself even loads! A "click" handler works fine, as expected. But changetext? Nope.
I've thrown together a simplified version to demonstrate. The line with the "DIES RIGHT HERE" comment causes the problem (not the comment, but the code to the left of it).
A textbox that is added at design time will work fine, not cause this problem, but that isn't an option.
What's causing this the changetext handler to be run early? How do I work around this?
Public Class Form1
Dim txtTest As TextBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim pntTextBox As Point
pntTextBox.X = 100
pntTextBox.Y = 100
txtTest = New TextBox
With txtTest
.Location = pntTextBox
.Width = 100
AddHandler txtTest.TextChanged, AddressOf txtTest_TextChanged
End With
Me.Controls.Add(txtTest)
End Sub
Private Sub txtTest_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyClass.TextChanged
Dim strTest As String
strTest = Str(txtTest.Width) ' ****** DIES RIGHT HERE
MsgBox(strTest)
End Sub
End Class
Made a few changes. Works.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For x As Integer = 1 To 2 'create multiple TB's
Dim pntTextBox As Point
pntTextBox.X = 100 * x
pntTextBox.Y = 100
Dim txtTest As TextBox = New TextBox
With txtTest
txtTest.Name = "tb_" & x.ToString
AddHandler txtTest.TextChanged, AddressOf txtTest_TextChanged
.Location = pntTextBox
.Width = 100
End With
Me.Controls.Add(txtTest)
Next
End Sub
Private Sub txtTest_TextChanged(ByVal sender As Object,
ByVal e As System.EventArgs) 'no handler at design time
Dim tb As TextBox = DirectCast(sender, TextBox)
Dim strTest As String
strTest = tb.TextLength.ToString
Debug.WriteLine("{0} {1}", tb.Name, strTest) 'put breakpoint here
End Sub
End Class

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.

Custom Textbox Zoom - Return text to active datagridview cell?

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.

How to customize the click event of dynamically created buttons from string array?

Here is the code I have:
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddNewButton()
End Sub
Public Sub AddNewButton()
Dim buttonTop As Integer = 100
For Each item As String In Globals.candidates
Dim btn As New System.Windows.Forms.Button()
Dim Location As New Point(100, (buttonTop + 20))
btn.Location = Location
btn.Text = item
btn.Width = 150
AddHandler btn.Click, AddressOf Me.buttonClick
Me.Controls.Add(btn)
buttonTop += 20
Next
End Sub
Private Sub buttonClick()
Dim result As Integer = MessageBox.Show(String.Format("Did you select {0} ?", ???????????), "Confirmation", MessageBoxButtons.YesNo)
If result = DialogResult.Yes Then
MessageBox.Show("Yes pressed")
Else
MessageBox.Show("No pressed")
End If
End Sub
End Class
Globals.candidates is a global string array variable that holds a name "LastName, FirstName" and when the form is loaded I call the AddNewButton() Sub and it creates buttons for each item in the string array. No problem.
If you see in my code the "??????????" section, I don't know how to reference the dynamically created buttons's text so that I can display the proper "Did you select thisButton.text" properly.
Any help is appreciated.
Thanks!
EDIT:
Code changed as per suggestions: (Working)
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddNewButton()
End Sub
Public Sub AddNewButton()
Dim buttonTop As Integer = 100
For Each item As String In Globals.candidates
Dim btn As New System.Windows.Forms.Button()
Dim Location As New Point(100, (buttonTop + 20))
btn.Location = Location
btn.Text = item
btn.Width = 150
AddHandler btn.Click, AddressOf Me.buttonClick
Me.Controls.Add(btn)
buttonTop += 20
Next
End Sub
Private Sub buttonClick(sender As Object, e As EventArgs)
Dim btn As Button = DirectCast(sender, System.Windows.Forms.Button)
Dim result As Integer = MessageBox.Show(String.Format("Did you select {0} ?", btn.Text), "Confirmation", MessageBoxButtons.YesNo)
If result = DialogResult.Yes Then
MessageBox.Show("Yes pressed")
Else
MessageBox.Show("No pressed")
End If
End Sub
End Class
You need to put the proper signature on your event handler:
Private Sub buttonClick(sender As Object, e As EventArgs)
Then, you can use the sender object (which will be whichever button was clicked)
Dim button As Button = DirectCast(sender, System.Windows.Forms.Button)
Dim result As Integer = MessageBox.Show(String.Format("Did you select {0} ?", button.Text), "Confirmation", MessageBoxButtons.YesNo)
To get a reference to the button clicked you need to declare the event handler of the button click with the two parameters that are passed to it by the form engine.
Private Sub buttonClick(sender as Object, e as EventArgs)
Now, this correct event handler receives a parameter named sender that is the control reference to the button clicked. You could cast it to a button and then extract the Text property
Private Sub buttonClick(sender as Object, e as EventArgs)
Dim btn = DirectCast(sender, System.Windows.Forms.Button)
if btn IsNot Nothing then
Dim result As Integer = MessageBox.Show(String.Format("Did you select {0} ?", btn.Text), "Confirmation", MessageBoxButtons.YesNo)
If result = DialogResult.Yes Then
MessageBox.Show("Yes pressed")
Else
MessageBox.Show("No pressed")
End If
End If
End Sub
This should be enough in this simple case where you have just a string data, but, if you need to associate a more complex object (like an instance of a Person class for example) you could use the Tag property of every dynamically added button to store there a reference to the instance of the class
As a side note, your code works also without the declaration of the two parameters because you have the Option Strict configuration set to OFF. This is a bad practice because it introduces subtle errors in you parameters usage and in automatic conversions of type. If you are just starting with a new project remember to set its property Option Strict to ON

Making combobox visible when it is disabled

I am disabling combobox in VB.net.
But in disable mode it not visible properly.
I tried changing both BackColor and ForeColor but it is not working.
Code :
cmbbox.BackColor = Color.FromName("Window")
or
cmbbox.ForeColor = Color.FromName("Window")
Please help
Dear Adam:
I am making my component enable false.But I want to make it viewable.You can reffer the link.This is what exacly I want but in VB.Net : A combobox that looks decent when it is disabled
To achieve disabling combobox without fading it, first change the dropdown style of the combobox to DropDownList, Then tweak with the events to achieve the goal.
Here is a piece of code by which you can achieve the same:
Public Class Form1
Dim selectindex As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.Items.Add("1")
ComboBox1.Items.Add("2")
ComboBox1.Items.Add("3")
ComboBox1.Items.Add("4")
selectindex = 3
ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
ComboBox1.SelectedIndex = selectindex
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted
ComboBox1.SelectedIndex = selectindex
End Sub
End Class
Create anew form Form1 and add a combobox to the form, then add the above code to get a readonly combobox.
Have a look at this thread which has a solution for a readonly combobox and the code is all VB.NET.
A version of their code is as follows. You'll need to but it inside a class of your own which inherits System.Windows.Forms.ComboBox
Private _ReadOnly As Boolean = False
Public Property [ReadOnly]() As Boolean
Get
Return _ReadOnly
End Get
Set(ByVal Value As Boolean)
_ReadOnly = Value
End Set
End Property
Public Overrides Function PreProcessMessage(ByRef msg As Message) As Boolean
'Prevent keyboard entry if control is ReadOnly
If _ReadOnly = True Then
'Check if its a keydown message
If msg.Msg = &H100 Then
'Get the key that was pressed
Dim key As Int32 = msg.WParam.ToInt32
'Ignore navigation keys
If key = Keys.Tab Or key = Keys.Left Or key = Keys.Right Then
'Do nothing
Else
Return True
End If
End If
End If
'Call base method so delegates receive event
Return MyBase.PreProcessMessage(msg)
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
'Prevent list displaying if ReadOnly
If _ReadOnly = True Then
If m.Msg = &H201 OrElse m.Msg = &H203 Then
Return
End If
End If
'Call base method so delegates receive event
MyBase.WndProc(m)
End Sub
I've been looking for the same not long ago and ended up doing the following. You may not like it, but i'll share it in case. I am using TableLayoutPanel to arrange my controls on the form and then i am swapping the positions of the desired controls.
For example I've created the following Items:
Form1 Design
TableLayoutPanel1 (two columns, three rows)
TextBox1 Read-only = True, BackColor = White
ComboBox1 Visible = False, DropDownStyle = DropDownList, FlatStyle = Popup
Button1 (named it to Change)
Button2 (named it to Done) -> Visible = False
Runtime - Screenshots
Here is my code:
Public Class Form1
Private Sub SwapControls(tlp As TableLayoutPanel, ctr1 As Control, ctr2 As Control)
Dim ctl1pos As TableLayoutPanelCellPosition = tlp.GetPositionFromControl(ctr1)
ctr1.Visible = False
tlp.SetCellPosition(ctr1, tlp.GetPositionFromControl(ctr2))
ctr2.Visible = True
tlp.SetCellPosition(ctr2, ctl1pos)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SwapControls(TableLayoutPanel1, TextBox1, ComboBox1)
SwapControls(TableLayoutPanel1, Button1, Button2)
Label1.Select()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
SwapControls(TableLayoutPanel1, ComboBox1, TextBox1)
SwapControls(TableLayoutPanel1, Button2, Button1)
Label1.Select()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Select()
ComboBox1.SelectedIndex = 0
TextBox1.Text = ComboBox1.SelectedItem
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
TextBox1.Text = ComboBox1.SelectedItem
End Sub
End Class