vb.net combobox to return value of another column - vb.net

I have two comboboxes. The second one is dependant on the first. I then pass the selected values to a second form as objects. My code works perfectly up to here. But I also need to pass a third object to the second form (i.e. plaasnopass) based on the selection of the second combobox (i.e cmbPlaasnaam). This value however is in another column. My code below runs without errors , but the third value is not passed to the second form.
Public Class ParskaartjieKiesFrm
Dim obj As New Parskaartjies
Private Sub ParskaartjieKiesFrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'SkeduleringDatabasisDataSet.wingrd13' table. You can move, or remove it, as needed.
Me.Wingrd13TableAdapter.Fill(Me.SkeduleringDatabasisDataSet.wingrd13)
With CmbAliasnaam
.BeginUpdate()
.AutoCompleteMode = AutoCompleteMode.SuggestAppend
.AutoCompleteSource = AutoCompleteSource.ListItems
Dim qry = From zc As SkeduleringDatabasisDataSet.wingrd13Row In SkeduleringDatabasisDataSet.wingrd13 _
Select zc.Aliasnaam Distinct Order By Aliasnaam
For Each ALIASNAAM As String In qry
.Items.Add(ALIASNAAM)
Next
.EndUpdate()
End With
With CmbPlaasnaam
.AutoCompleteMode = AutoCompleteMode.SuggestAppend
.AutoCompleteSource = AutoCompleteSource.ListItems
.Enabled = False
End With
End Sub
Private Sub CmbAliasnaam_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbAliasnaam.SelectedIndexChanged
obj.aliasnaampass = CmbAliasnaam.SelectedItem
With CmbPlaasnaam
.SelectedIndex = -1
.Items.Clear()
.Enabled = False
End With
If CmbAliasnaam.SelectedIndex > -1 Then
CmbPlaasnaam.BeginUpdate()
Dim Aliasnaam As String = CmbAliasnaam.Items(CmbAliasnaam.SelectedIndex).ToString
Dim qry = From zc As SkeduleringDatabasisDataSet.wingrd13Row In SkeduleringDatabasisDataSet.wingrd13 _
Where zc.Aliasnaam = ALIASNAAM Select zc.Plaasnaam Distinct _
Order By Plaasnaam
For Each plaasnaam As String In qry
CmbPlaasnaam.Items.Add(plaasnaam)
Next
If CmbPlaasnaam.Items.Count > 0 Then
CmbPlaasnaam.Enabled = True
End If
CmbPlaasnaam.EndUpdate()
End If
End Sub
Private Sub CmbPlaasnaam_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbPlaasnaam.SelectedIndexChanged
obj.plaasnaampass = CmbPlaasnaam.SelectedItem
obj.plaasnopass = CmbAliasnaam.SelectedValue
obj.Show()
Me.Close()
End Sub
End Class
How do I go about ?
Regards

According to your comment, I understood that you have combo box loaded from
select a from t
but this gives you single value, and you want to load
select a, b from t
and pass both values to next form.
It is helpful that you're using LINQ!! Modify it. But first declare new type
Public Class CboItem
Public Property Display As String
Public Property Value As String ' <-- any datatype
' .... any number of properties here
End Class
Dim qry =
(From zc As SkeduleringDatabasisDataSet.wingrd13Row
In SkeduleringDatabasisDataSet.wingrd13 _
Where zc.Aliasnaam = ALIASNAAM
Select New CboItem() With { .Display = zc.Plaasnaam, .Value = zs.[...] }).
Distinct(function(item)...).OrderBy(function(item)...)
CmbAliasnaam.DisplayMember = "Display"
CmbAliasnaam.ValueMember = "Value"
CmbAliasnaam.DataSource = qry.ToList()
Now you can pass to your form selected item or whatever you get out of it. for example
Dim item As CboItem = TryCast(CmbAliasnaam.SelectedItem, CboItem)
If item IsNot Nothing Then
frm.SetSelected(item.Display, item.Value, item.anyOtherProperty)
End If
' or
frm.SomeProperty = item
As you see, you can pass an object that you can store in combo box. It doesn't have to be string.

Related

VB.Net populating text boxes from text file

I'm creating an inventory management system where the data is stored in a text file. I'm able to save data to the text file, however on the tracker screen it should show current inventory such as: Manufacturer, Processor, Video, Form, RAM, etc. However, all my text boxes remain blank and I'm not sure why. It's not reading properly or updating the text.
frmTracker.vb
Private Sub txtManufacturer_TextChanged(sender As Object, e As EventArgs) Handles txtManufacturer.TextChanged
Dim objMyStreamReader = System.IO.File.OpenText("inventory.txt")
Dim strInventory = objMyStreamReader.ReadLine()
objMyStreamReader.Close()
txtManufacturer.AppendText(strInventory)
End Sub
This is how I'm currently saving the data to the text file.
frmItemEntry.vb
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim objMyStreamReader As System.IO.StreamReader
Dim objMyStreamWriter As System.IO.StreamWriter = System.IO.File.CreateText("inventory.txt")
Dim strInventory As String
objMyStreamWriter.WriteLine(txtManufacturerEntry.Text)
objMyStreamWriter.WriteLine(txtProcessorEntry.Text)
objMyStreamWriter.WriteLine(txtVideoEntry.Text)
objMyStreamWriter.WriteLine(txtFormEntry.Text)
objMyStreamWriter.WriteLine(txtRamEntry.Text)
objMyStreamWriter.WriteLine(txtVramEntry.Text)
objMyStreamWriter.WriteLine(txtHdEntry.Text)
objMyStreamWriter.WriteLine(chkWirelessEntry.CheckState)
objMyStreamWriter.Close()
Me.Close()
End Sub
Example from inventory.txt
Dell
i5
Nvidia
Desktop
8
4
600
0
To be honest, controls should never be used as the primary store for your data in a program. You should really be creating a class and a list of that class to store your data.
You can then read your data into the list from your file, and then, display it from there in your form.
There are several ways of navigating through the data and saving updates. The suggestion below uses buttons for next item and previous item, and a button to save update the file.
It's all pretty self explanatory, but if there's something your not sure about, please have a google and learn something new :-D
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ReadDataFile()
DisplayItem(0)
End Sub
Private Class InventoryItem
Public Property Manufacturer As String
Public Property Processor As String
Public Property Video As String
Public Property FormFactor As String
Public Property Ram As String
Public Property VRam As String
Public Property Hd As String
Public Property Wireless As CheckState
Public Sub New()
Manufacturer = ""
Processor = ""
Video = ""
FormFactor = ""
Ram = ""
VRam = ""
Hd = ""
Wireless = CheckState.Unchecked
End Sub
End Class
Dim Inventory As New List(Of InventoryItem)
Dim currentItemIndex As Integer
Private Sub ReadDataFile()
Using objMyStreamReader As New StreamReader("k:\inventory.txt")
Do Until objMyStreamReader.EndOfStream
Dim newItem As New InventoryItem
newItem.Manufacturer = objMyStreamReader.ReadLine()
newItem.Processor = objMyStreamReader.ReadLine()
newItem.Video = objMyStreamReader.ReadLine()
newItem.FormFactor = objMyStreamReader.ReadLine()
newItem.Ram = objMyStreamReader.ReadLine()
newItem.VRam = objMyStreamReader.ReadLine()
newItem.Hd = objMyStreamReader.ReadLine()
Dim wirelessValue As String = objMyStreamReader.ReadLine()
If wirelessValue = "0" Then
newItem.Wireless = CheckState.Unchecked
ElseIf wirelessValue = "1" Then
newItem.Wireless = CheckState.Checked
End If
Inventory.Add(newItem)
Loop
End Using
End Sub
Private Sub SaveDataFile()
Using objMyStreamWriter As New System.IO.StreamWriter("k:\inventory.txt", False)
For Each item As InventoryItem In Inventory
objMyStreamWriter.WriteLine(item.Manufacturer)
objMyStreamWriter.WriteLine(item.Processor)
objMyStreamWriter.WriteLine(item.Video)
objMyStreamWriter.WriteLine(item.FormFactor)
objMyStreamWriter.WriteLine(item.Ram)
objMyStreamWriter.WriteLine(item.VRam)
objMyStreamWriter.WriteLine(item.Hd)
If item.Wireless = CheckState.Checked Then
objMyStreamWriter.WriteLine("1")
Else
objMyStreamWriter.WriteLine(0)
End If
Next
End Using
End Sub
Private Sub DisplayItem(index As Integer)
With Inventory(index)
txtManufacturerEntry.Text = .Manufacturer
txtProcessorEntry.Text = .Processor
txtVideoEntry.Text = .Video
txtFormEntry.Text = .FormFactor
txtRamEntry.Text = .Ram
txtVramEntry.Text = .VRam
txtHdEntry.Text = .Hd
chkWirelessEntry.CheckState = .Wireless
End With
End Sub
Private Sub BtnUpdateItem_Click(sender As Object, e As EventArgs) Handles BtnUpdateItem.Click
With Inventory(currentItemIndex)
.Manufacturer = txtManufacturerEntry.Text
.Processor = txtProcessorEntry.Text
.Video = txtVideoEntry.Text
.FormFactor = txtFormEntry.Text
.Ram = txtRamEntry.Text
.VRam = txtVramEntry.Text
.Hd = txtHdEntry.Text
.Wireless = chkWirelessEntry.CheckState
End With
SaveDataFile()
End Sub
Private Sub BtnPreviousItem_Click(sender As Object, e As EventArgs) Handles BtnPreviousItem.Click
If currentItemIndex > 0 Then
currentItemIndex -= 1
DisplayItem(currentItemIndex)
End If
End Sub
Private Sub BtnNextItem_Click(sender As Object, e As EventArgs) Handles BtnNextItem.Click
If currentItemIndex < Inventory.Count - 1 Then
currentItemIndex -= 1
DisplayItem(currentItemIndex)
End If
End Sub
First change the format of your text file.
Dell,i5,Nvidia,Desktop,8,2,600,True
Acer,i7,Intel,Desktop,16,4,1GB,True
HP,Pentium,Diamond Viper,Desktop,4,2,200,False
Surface Pro,i7,Intel,Laptop,8,2,500,True
Each line is a record and each field in the record is separated by a comma (no spaces so we don't have to .Trim in code) (a space within a field is fine, notice Surface Pro).
Now it is easier to read the file in code.
This solution uses a BindingSource and DataBindings. This simplifies Navigation and editing and saving the data.
Public Class Form5
Private bs As BindingSource
Private dt As New DataTable
#Region "Set Up the Form"
Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddColumnsToDataTable()
FillDataTable()
AddDataBindings()
End Sub
Private Sub AddColumnsToDataTable()
'Prepare the DataTable to hold data
dt.Columns.Add("Manufacturer", GetType(String))
dt.Columns.Add("Processor", GetType(String))
dt.Columns.Add("Video", GetType(String))
dt.Columns.Add("Form", GetType(String))
dt.Columns.Add("RAM", GetType(String))
dt.Columns.Add("VRAM", GetType(String))
dt.Columns.Add("HD", GetType(String))
dt.Columns.Add("Wireless", GetType(Boolean))
End Sub
Private Sub FillDataTable()
'ReadAllLines returns an array of the lines in a text file
'inventory.txt is stored in the bin\Debug folder of your project
'This is the current directory so it does not require a full path.
Dim lines = File.ReadAllLines("inventory.txt")
'Now it is easy to split each line into fields by using the comma
For Each line As String In lines
'Split returns an array of strings with the value of each field
Dim items = line.Split(","c)
'Each item in the array can be added as a field to the DataTable row
dt.Rows.Add(items(0), items(1), items(2), items(3), items(4), items(5), items(6), CBool(items(7)))
'Notice that the last element is changed from a string to a boolean. This is
'the Wireless field which is bound to the check box. The string "True" or "False" is
'changed to a Boolean so it can be used as the .Checked property (see bindings)
Next
End Sub
Private Sub AddDataBindings()
'Create a new instance of the BindingSource class
bs = New BindingSource()
'Set the DataSource to the DataTable we just filled
bs.DataSource = dt
'Now you can set the bindings of each control
'The .Add method takes (Name of Property to Bind, the BindingSource to use, The Field name
'from the DataTable.
txtForm.DataBindings.Add("Text", bs, "Form")
txtHd.DataBindings.Add("Text", bs, "HD")
txtManufacturer.DataBindings.Add("Text", bs, "Manufacturer")
txtProcessor.DataBindings.Add("Text", bs, "Processor")
txtRam.DataBindings.Add("Text", bs, "RAM")
txtVideo.DataBindings.Add("Text", bs, "Video")
txtVram.DataBindings.Add("Text", bs, "VRAM")
'Notice on the CheckBox we are using the Checked property.
chkWireless.DataBindings.Add("Checked", bs, "Wireless")
End Sub
#End Region
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
'Add a blank row to the DataTable
'A Boolean is like a number, a String can be Nothing but a Boolean must
'have a value so we pass in False.
dt.Rows.Add(Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, False)
'Find the position of the last row
Dim i As Integer = bs.Count - 1
'Move to the new empty row
bs.Position = i
End Sub
#Region "Navigation Code"
Private Sub btnPrevious_Click(sender As Object, e As EventArgs) Handles btnPrevious.Click
'The binding source Position determins where in the data you are
'It starts at zero
If bs.Position = 0 Then
MessageBox.Show("This is the first item.")
Return 'This exits the sub, you can use Exit Sub in vb
'but Return is common in other languages so it is good to learn
Else
'As the position of the BindingSource changes the boud TextBoxes
'change their data.
bs.Position = bs.Position - 1
End If
End Sub
Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
' If you are not at the end of the list, move to the next item
' in the BindingSource.
If bs.Position + 1 < bs.Count Then
bs.MoveNext()
' Otherwise, move back to the first item.
Else
bs.MoveFirst()
End If
End Sub
#End Region
#Region "Save the Data"
Private Sub SaveDataTable()
'Resave the whole file if this was a real app you would use a database
Dim sb As New StringBuilder
'A string builder keeps the code from creating lots of new strings
'Strings are immutable (can't be changed) so every time you think you are
'changing a string, you are actually creating a new one.
'The string builder is mutable (changable)
For Each row As DataRow In dt.Rows
'The ItemsArray returns an array of objects containing all the
'values in each column of the data table.
Dim rowValues = row.ItemArray
'This is a bit of Linq magic that turns the values (objects) into strings
'Underneath it is performing a For loop on each object in the array
Dim strRowValues = From o In rowValues
Select Convert.ToString(o)
'Now that we have strings we can use the String.Join with the comma
'to get the format of the text file
sb.AppendLine(String.Join(",", strRowValues))
Next
'Finally we change the StringBuilder to a real String
'The inventory.txt is stored in the bin\Debug directory so it is current directory
'no additional path required
File.WriteAllText("inventory.txt", sb.ToString)
End Sub
Private Sub Form5_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
'Because our binding is two-way any additions or changes to the text
'in the text boxes or check box are reflected in the DataTable.
SaveDataTable()
End Sub
#End Region
End Class
Once you remove the comments, there is really very little code here. The #Region...#End Region tags make it easy to collapse code sections you are not working on and find areas quickly.

How to print main, customer and duplicate copy in Crystal Report

How to print first time Main Copy
second time Customer Copy
third or more time Duplicate Copy
My requirement is as in the image below:
VB Code
At first do Import
Imports System.Web.UI.WebControls
Public Sub ShowReport(ByVal MyReport As CrystalDecisions.CrystalReports.Engine.ReportDocument, ByVal filterstring As String, ByVal CrystalReportViewer As CrystalDecisions.Windows.Forms.CrystalReportViewer)
Dim myLogonInfo As New CrystalDecisions.Shared.TableLogOnInfo
Dim myTable As Table
For Each myTable In MyReport.Database.Tables
myLogonInfo = myTable.LogOnInfo
'myLogonInfo.ConnectionInfo.ServerName = Application.StartupPath & "\" & "data.mdb"
myLogonInfo.ConnectionInfo.ServerName = My.Settings.RptserverPath.ToString
myLogonInfo.ConnectionInfo.DatabaseName = My.Settings.Database.ToString
myLogonInfo.ConnectionInfo.UserID = My.Settings.DBUser.ToString
myLogonInfo.ConnectionInfo.Password = My.Settings.DBPass.ToString
myTable.ApplyLogOnInfo(myLogonInfo)
Next myTable
End Sub
Private Sub SimpleButton4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SimpleButton4.Click
For reportType As Integer = 1 To 3
Dim MyReport As CrystalDecisions.CrystalReports.Engine.ReportDocument = New RecipeWithOutCostingSheet
MyReport.SetParameterValue("paramReportType", reportType)
PrintReport(MyReport, filterstring, CrystalReportViewer1, PrintDialog1)
Next
End Sub
Crystal report Formula Create formula name paramReportType
Select {?paramReportType}
Case 1 :
"Main Copy"
Case 2 :
"Customer Copy"
Default :
"Duplicate Copy"
Put on your Report Location.
In your code
Dim rpt As New CrystalDecisions.CrystalReports.Engine.ReportDocument
rpt.Load("<report name>")
rpt.SetDataSource(your datasource)
For reportType As Integer = 1 To 3
rpt.SetParameterValue("paramReportType", reportType)
' show your report in a dialog window
ShowReport(rpt)
Next
Public Sub ShowReport(ByRef oRpt As Object)
Using frm As New ReportViewer
With frm
.Icon = frmMain.Icon
.Report = oRpt
.ShowDialog()
End With
End Using
End Sub
Inside ReportViewer form (with 1 CrystalReportViewer control named crv)
Public Class ReportViewer
Dim oReport As Object
Public WriteOnly Property Report() As Object
Set(ByVal value As Object)
oReport = value
End Set
End Property
Private Sub ReportViewer_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Try
Me.Cursor = Cursors.WaitCursor
crv.ReportSource = oRpt
Catch ex As Exception
Msgbox(ex.Message)
Finally
Me.Cursor = Cursors.Default
End Try
End Sub
End Class
In your report, create a parameter value named paramReportType with a type of Number.
Then, also inside your report, create a formula field (I'm using Basic syntax)
select case {?paramReportType}
case 1
formula = "Main Copy"
case 2
formula = "Customer Copy"
case 3
formula = "Duplicate Copy"
end select
Then add the formula field to your report, instead of a Text object.

Object returns null when it is not

I basically i have two forms, one named 'frmSettings' and another names 'frmXLExternalFile', 'frmXLExternalFile' is created from 'frmSettings', there is data passed between these two forms and when i return it using a property it returns as null. Ive tried returning it by settings it to public but that still doesnt seem to work some strange reason. I've set breakpoints and traced the variable ( actually a structure ) and it is certainly not 'null'
frmXLExternalFile
Dim XL_File As frmMain.XLSheetData
Public ReadOnly Property XLFile As frmMain.XLSheetData
Get
Return XL_File
End Get
End Property
Private Sub frmXLExternalFile_formClosing(sender As Object, e As EventArgs) Handles MyBase.FormClosing
If txtFilepath.Text <> "" And cmboName.Text <> "" Then
XL_File = New frmMain.XLSheetData
XL_File.name = cmboName.Text
XL_File.filePath = txtFilepath.Text
frmMain.settings.setXLFile()
frmMain.settings.cmboXLSheets.Text = txtFilepath.Text
End If
frmMain.settings.Enabled = True
End Sub
frmMain (This is where the structure is declared)
Public Structure XLSheetData
Dim name As String
Dim filePath As String
End Structure
frmSettings
Dim XL_FileList As List(Of frmMain.XLSheetData)
Sub setXLFile()
Dim file As frmMain.XLSheetData = frmXLExternalFile.XLFile
XL_FileList.Add(file)
cmboXLSheets.Items.Add(file.filePath)
End Sub
basically, The top form calls this the bottom method once the field - XL_File - is filled, this then uses the property - 'XLFile' - to 'Get' the object and put it in the 'frmSettings' class. As I have said, i have tried setting 'XL_File' to public and tried accessing it directly but the same exception is thrown. It is null, the combo box and text box that are used to fill the object are not null. Any help would be appreciated. Thanks.
Here's one way to do it with Show(), by passing in the "Owner" form:
In frmSettings:
Dim frmX As New frmXLExternalFile
' ... pass some data to frmX ...
frmX.Show(Me) ' <-- pass this form in as the "Owner"
In frmXLExternalFile:
Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
If txtFilepath.Text <> "" And cmboName.Text <> "" Then
XL_File = New frmMain.XLSheetData
XL_File.name = cmboName.Text
XL_File.filePath = txtFilepath.Text
Dim main As frmSettings = DirectCast(Me.Owner, frmSettings) ' <-- use the instance passed in as the owner via Show()
' ... use "main" somehow ...
main.settings.setXLFile()
main.settings.cmboXLSheets.Text = txtFilepath.Text
main.settings.Enabled = True
Else
' ... possibly do something else ...
End If
End Sub
This example demonstrates a ShowDialog() approach:
In frmSettings:
Dim frmX As New frmXLExternalFile
' ... pass some data to frmX ...
If frmX.ShowDialog() = Windows.Forms.DialogResult.OK Then ' <-- execution in this Form STOPS until "frmX" is dismissed
' Retrieve the value from out "frmX" instance:
Dim file As frmMain.XLSheetData = frmX.XLFile
' ... do something with "file" ...
XL_FileList.Add(file)
cmboXLSheets.Items.Add(file.filePath)
cmboXLSheets.Text = file.filePath
End If
In frmXLExternalFile:
Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
If txtFilepath.Text <> "" And cmboName.Text <> "" Then
XL_File = New frmMain.XLSheetData
XL_File.name = cmboName.Text
XL_File.filePath = txtFilepath.Text
' Set DialogResult, returning execution to the ShowDialog() line:
Me.DialogResult = Windows.Forms.DialogResult.OK
Else
' ... possibly do something else ...
End If
End Sub

vb.net Find Form

In the Windows, the native Notepad program has a find form. Basically When the user types and hits 'Find Next', the program proceeds to find the text while keeping the focus on the Find form. This way the user can keep hitting the 'Enter' key or the button and still have the text highlighted while the form is focused.
My problem is that I have a different form for the "Search" feature and whenever the user hits "Enter" the text is found and the focus is set on the TextBox but when the user hits "Enter" again, the text gets edited because of the focus.
Currently, I'm using Regex to do this and I am using a WPF TextBox using HostElement:
Private Function GetRegExpression() As Regex
Dim result As Regex
Dim regExString As [String]
regExString = txtbx_Find.Text
If matchCaseCheckBox.Checked Then
result = New Regex(regExString)
Else
result = New Regex(regExString, RegexOptions.IgnoreCase)
End If
Return result
End Function
Private Sub FindText()
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
If isFirstFind Then
regex = GetRegExpression()
match = regex.Match(TheTextBox.Text)
isFirstFind = False
Else
match = regex.Match(TheTextBox.Text, match.Index + 1)
End If
If match.Success Then
Dim row As Integer = TheTextBox.GetLineIndexFromCharacterIndex(TheTextBox.CaretIndex)
MoveCaretToLine(TheTextBox, row + 1)
TheTextBox.SelectionStart = match.Index
TheTextBox.SelectionLength = match.Length
TheTextBox.Focus()
Me.Focus()
Else
MessageBox.Show([String].Format("Cannot find ""{0}"" ", txtbx_Find.Text), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)
isFirstFind = True
End If
End Sub
Private Sub btn_FindNext_Click(sender As Object, e As EventArgs) Handles btn_FindNext.Click
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
FindText()
'theTextBox.Focus()
End Sub
I want it to be just like Notepad where the user hits "Enter" and keeps focus on the Find Form while selecting the text. How can this be achieved?
I think you should catch "keyup" event of your form like this :
Class MainWindow
Private Sub Window_KeyUp(sender As System.Object, e As System.Windows.Input.KeyEventArgs) Handles MyBase.KeyUp
If e.Key = Key.Enter Then
FindNext()
End If
End Sub
Private Sub btn_FindNext_Click(sender As Object, e As EventArgs) Handles btn_FindNext.Click
FindText()
End Sub
Private Sub FindNext()
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
FindText()
'theTextBox.Focus()
End Sub
End Class

Send value to parent then close child form, on event

I have a parent form with a combobox populated from a database, from which the user can select. The last value in the combo box is "add new", if the user selects this, a child form opens for the user to add a new value to the database. I have a button press event to add this value to the database, send the new return value to the parent and close the form. The parent should then select the new value from it's combo box and wait for the user to perform another action.
However, the code to send the return value to parent and close the form isn't working correctly. I hide the child, then call a function on it with the parent to access the return value. At this point the child form shows and the code stops before it runs another hide or close.
How can I fix this (code below)?
Parent Combobox event:
Private Sub cmbLocations_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cmbLocations.SelectedIndexChanged
If Not cmbLocations.SelectedIndex = -1 Then
If cmbLocations.SelectedIndex = cmbLocations.Items.Count - 1 Then
If diaAddLocation.IsAccessible = False Then diaAddLocation.Activate()
diaAddLocation.RequestSender = Me
diaAddLocation.ShowDialog()
FillLocations()
cmbLocations.SelectedIndex = LocationFromLocationName(diaAddLocation.formresult)
diaAddLocation.Close()
diaAddLocation.Dispose()
Else
bttYes.Enabled = True
End If
End If
End Sub
Child Button Press and Return value function
Public Sub bttAddLOCtoDatabase_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttAddLOCtoDatabase.Click
Dim LocationToBeAdded As String
LocationToBeAdded = "'" & TextBox1.Text & "'"
AddLocation("'" & textbox1.Text & "'")
FormResult = textbox1.Text
GetLocations()
frmFieldMaster.InitialiseNewParameter()
Me.Hide()
End Sub
Public Function Result() As String
Return FormResult
End Function
EDIT:
code with Steve's solution implemented:
Public Sub bttAddLOCtoDatabase_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttAddLOCtoDatabase.Click
Dim LocationToBeAdded As String
LocationToBeAdded = "'" & TextBox1.Text & "'"
AddLocation("'" & textbox1.Text & "'")
FormResult = textbox1.Text
GetLocations()
frmFieldMaster.InitialiseNewParameter()
DialogResult = Windows.Forms.DialogResult.OK
'me.Hide()
End Sub
Public Function Result() As String
Return FormResult
Me.Close()
End Function
Private Sub cmbLocations_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cmbLocations.SelectedIndexChanged
Dim ValueTaken As Boolean = False
If Not cmbLocations.SelectedIndex = -1 Then
If cmbLocations.SelectedIndex = cmbLocations.Items.Count - 1 Then
Using diaaddlocation = New diaAddLocation
diaaddlocation.requestsender = Me
If DialogResult.OK = diaaddlocation.showdialog Then
FillLocations()
cmbLocations.SelectedIndex = LocationFromLocationName(diaaddlocation.result)
diaaddlocation.close()
ElseIf DialogResult.Cancel = diaaddlocation.showdialog Then
cmbLocations.SelectedIndex = -1
End If
End Using
Else
bttYes.Enabled = True
End If
End If
End Sub
When I run the code it enters IF DialogResult.OK... and opens the child. Then when I close the child the parent runs the next two lines of code and get the result from the child. After this the parent runs the line IF DialogResult.OK... again and stops with the child open. The code never reaches the diaaddlocation.close line.
You don't need all of this. You could try something like this
If cmbLocations.SelectedIndex = cmbLocations.Items.Count - 1 Then
Using diaAddLocation = new diaAddLocation()
diaAddLocation.RequestSender = Me
if DialogResult.OK = diaAddLocation.ShowDialog() then
FillLocations()
cmbLocations.SelectedIndex = LocationFromLocationName(diaAddLocation.formresult)
End If
End Using
Else
.....
This requires the DialogResult property for bttAddLOCtoDatabase set to DialogResult.OK and the child form AcceptButton property set to bttAddLOCtoDatabase. Now you could remove the Hide() call inside the bttAddLOCtoDatabase_Click method
This works because, until you don't exit the Using statement, your child form is still available to read its properties (results)
EDIT: Not related to the main problem, but these lines are wrong:
ElseIf DialogResult.Cancel = diaaddlocation.showdialog Then
cmbLocations.SelectedIndex = -1
you should go with
Using diaAddLocation = new diaAddLocation()
diaAddLocation.RequestSender = Me
Dim dr = diaAddLocation.ShowDialog()
if dr = DialogResult.OK then
....
else if dr = DialogResult.Cancel then
....
end if
I don’t understand what is issue but if you are not getting value of “FormResult”
It doesn’t matter if you close from but it will be better to set DialogResult before closing it, cause you are showing it as dialog (showdialog)
Verify that diaAddLocation is instance of you window not the window class directly
If name of you form is frmdiaAddLocation then do not use it like
frmdiaAddLocation.showdialog
use it like
Dim diaAddLocation AS frmdiaAddLocation = New frmdiaAddLocation()
diaAddLocation.ShowDialog()
only using like this way will provide you result value