Passing parameters between two forms in VB.Net - vb.net

I currently have about 5 forms in my application. I'm building a 6th form - frmSummary however, I'd like to be able to access it from all forms. in frmSummary I am planning to add a DataGridView, where I'll be displaying data related to that form. I'm thinking that I should either create a global variable such as
dim FrmName as String
In each form I would have a cmdSummary button so that On click_event, I would do something like
frmName ="CustomerInfo"
Currently the way my application is set up is that I hve a mdiForm and within it, each form is a child so on opening new forms I do something like...
Private Sub cmdSummary_Click(sender As Object, e As EventArgs) Handles cmdSummary.Click
Dim NewMDIChild As New frmClientEligibilityReferral()
frmName = "CustomerInfo" --since this will be comeing from frmCustomerInfo
NewMDIChild.MdiParent = MDIform1
NewMDIChild.Show()
MDIForm1.Show()
End Sub
So I do something like that on opening my new form. My question is how can I pass the parameter to my form frmSummary....here's currently what I'm trying to accomplish....
Private Sub FrmSummary_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.MdiParent = MDIForm1
InitializeComponent()
'Here I want to call a function to load the datagridView(with g_frmName)see below...
call LoadDataGrid(frmName)
End Sub
Is something like that a smart idea? Or should I/Can I directly call the function from the previous form?
Just trying to see if I'm on the right track, if not, how can i do it in a sound way?

If there is only one frmSummary, you could make it a singleton.
In frmSummary, put the following code:
Private Shared _instance As frmSummary
Private Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
Public Shared Function GetInstance() As frmSummary
If _instance Is Nothing Then
_instance = New frmSummary()
End If
Return _instance
End Function
Public Sub PutDataInGrid(data As Object)
Me.DataGridView1.' put data in it
End Sub
And you would access it from other forms like this
Dim myFrmSummary = frmSummary.GetInstance()
myFrmSummary.PutDataInGrid(myData)

If I understand the question correctly....
You can just set the required parameters in the New declaration sub (Where InitializeComponent() is supposed to be). On your form, declare variables and set one to each of the parameter values, and set up your form this way..
An example might be;
Public Class frmSummary
Dim var1 as String = ""
Dim var2 as Boolean = True
Public Sub New(ByVal parameter1 as String, ByVal parameter2 As Boolean)
var1 = parameter1
var2 = parameter2
InitializeComponent()
End Sub
Private Sub frmSummary_Load(sender as Object, e As EventArgs) Handles MyBase.Load
If var1 = "This String" Then
If var2 = False Then
sql = "SELECT * FROM myTable"
' Rest of your code to get the DGV data
DataGridView1.DataSource = Dt
Else
End If
End If
End Sub
Again, I may have misunderstood the question, so apologies if that is the case.

Related

How can i pass parameters from datagridview to an open or main form without opening new form

I was thinking how can i pass parameters using constructors from datagridview which is in another form to my main form without opening new one. here's my code
-----------Main form constructor----------------------------------------
Public Sub New(customerID As Integer, fullName As String, phoneNumber As String, emailID As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_customerID = customerID
_fullName = fullName
_phoneNumber = phoneNumber
_emailID = emailID
End Sub
-----------------------------second form edit button click ----------------------------
Private Sub btnEdit_Click(sender As Object, e As EventArgs) Handles btnEdit.Click
Dim formMain As New frmMain(CInt(Me.dgvCustomerInfo.Item(0, Me.dgvCustomerInfo.SelectedRows(0).Index).Value),
Me.dgvCustomerInfo.Item(1, Me.dgvCustomerInfo.SelectedRows(0).Index).Value,
Me.dgvCustomerInfo.Item(2, Me.dgvCustomerInfo.SelectedRows(0).Index).Value,
Me.dgvCustomerInfo.Item(3, Me.dgvCustomerInfo.SelectedRows(0).Index).Value)
Me.Hide()
'formMain.Hide()
formMain.Show()
Thanks
You could create a property in your second form which is a list of the type of value that you want to pass and then when you create the form, assign your values to the property. Finally process the property using code in the form2.Shown event like this
Public Class Form1
Private Sub test()
Dim f2 As New form2
f2.formparameters = {4, 5, 6, 7}
f2.Show()
End Sub
End Class
And in your 2nd form write something like this..
Public Class form2
Friend Property formparameters() As Integer()
Private Sub form2_Shown(sender As Object, e As EventArgs) Handles Me.Shown
'process parameter data here
Me.Update()
End Sub
End Class

Bind DataSource to new DevExpress Report Designer?

I'm trying to figure out how to set my DataSource as the default when a user clicks New Report, or for any new report, in the DevExpress User Data Report Designer.
Right now, the Blank Report I have load on Form_Load has my DataSources just fine, but anytime I hit New Report, they're gone.
I've googled and followed the docs, but they all seem to be geared towards opening a specific report (as above).
Can anyone help?
0. ICommandHandler interface
You need to handle the ReportCommand.NewReport command by implementing the ICommandHandler interface. You must pass an object that implementing this interface to the XRDesignMdiController.AddCommandHandler method. You can get XRDesignMdiController object from ReportDesignTool.DesignForm.DesignMdiController property or from ReportDesignTool.DesignRibbonForm.DesignMdiController property according to what type of form you want to use.
Here is example:
Private Sub ShowReportDesigner()
Dim tool As New ReportDesignTool(CreateReport)
Dim controller = tool.DesignRibbonForm.DesignMdiController
Dim handler As New NewCommandHandler(controller, AddressOf CreateReport)
controller.AddCommandHandler(handler)
tool.ShowRibbonDesigner()
End Sub
Private Function CreateReport() As XtraReport
Dim report As New XtraReport
report.DataSource = YourDataSourceObjectHere
Return report
End Function
Public Class NewCommandHandler
Implements ICommandHandler
Private ReadOnly _controller As XRDesignMdiController
Private ReadOnly _createReport As Func(Of XtraReport)
Public Sub New(controller As XRDesignMdiController, createReport As Func(Of XtraReport))
_controller = controller
_createReport = createReport
End Sub
Public Function CanHandleCommand(command As ReportCommand, ByRef useNextHandler As Boolean) As Boolean Implements ICommandHandler.CanHandleCommand
useNextHandler = command <> ReportCommand.NewReport
Return Not useNextHandler
End Function
Public Sub HandleCommand(command As ReportCommand, args() As Object) Implements ICommandHandler.HandleCommand
_controller.OpenReport(_createReport())
End Sub
End Class
1. DesignPanelLoaded event
The another way is to subscribe to XRDesignMdiController.DesignPanelLoaded event. In this event you can check where the DataSource of report in loaded panel is empty and set it to your data source.
Here is example:
Private Sub ShowReportDesigner()
Dim report As New XtraReport
report.DataSource = YourDataSourceObjectHere
Dim tool As New ReportDesignTool(New XtraReport)
Dim controller = tool.DesignRibbonForm.DesignMdiController
AddHandler controller.DesignPanelLoaded, AddressOf mdiController_DesignPanelLoaded
tool.ShowRibbonDesigner()
End Sub
Private Sub mdiController_DesignPanelLoaded(ByVal sender As Object, ByVal e As DesignerLoadedEventArgs)
Dim panel = DirectCast(sender, XRDesignPanel)
Dim report = panel.Report
If IsNothing(report.DataSource) Then
report.DataSource = YourDataSourceObjectHere
End If
End Sub

Form data erased after Windows form is closed

I have a subsidiary form where I can enter data and then save it before closing the form and going back to using the main form.
When I re-open the subsidiary form, I cannot see the changes in the data that I had entered earlier.
Can anyone tell me where I'm wrong ?
MainForm.vb
Public Class Maincls
oTestObj as New Testcls
oTestObj.XYZ = "XYZ"
Private Sub SoftwareSettingsToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SoftwareSettingsToolStripMenuItem.Click
Testcls.tbXYZ.Text = oTestObj.m_XYZ
Testcls.Show()
End Sub
End Class
Form_Testcls.vb
Public Class Testcls
Structure Params
Dim m_XYZ as String
End Structure
Dim oParams as Params
Public Sub New ()
InitializeComponent()
End Sub
Private Sub btnOK_Click(sender As System.Object, e As System.EventArgs) Handles btnOK.Click
XYZ = tbXYZ.Text
Me.Hide()
End Sub
Public Property XYZ() As String
Get
Return Me.oparams.m_XYZ
End Get
Set(ByVal value As String)
Me.oparams.m_XYZ = value
End Set
End Property
End Class
I think in windows forms the work around for this is to create a static class and add properties according to your requirement. Then populate these static properties on closing of your form. Now you can use the value set in the static data members, unless otherwise you change them on any other event.
Edit: In vb.net the Static is actually NonInheritable

When can I access a form's members?

At first I tried this:
Public Class frmWait
Public Sub New(ByVal uWindowText As String, ByVal uInfoText As String)
Me.Text = uWindowText
Me.lblInfoText.Text = uInfoText
End Sub
End Class
But when I initiated the form like this
Dim wait As New frmWait("blah", "blah")
wait.Show()
... it told me "NullReference Exception" at this line:
Me.lblInfoText.Text = uInfoText
Settings the form's text worked fine.
Okay, I subspected the label was just not created yet when I tried to set the text.
Then I tried the following. I stored the texts in a variable and wanted to set them when the controls have been created. I thought "Form_Load" was a good event for that:
Public Class frmWait
Private m_sWindowText As String = ""
Private m_sInfoText As String = ""
Public Sub New(ByVal uWindowText As String, ByVal uInfoText As String)
'we can not set the texts right away because lblInfo does not seem to exist yet
m_sWindowText = uWindowText
m_sInfoText = uInfoText
End Sub
Private Sub frmWait_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.Text = m_sWindowText
Me.lblInfoText.Text = m_sInfoText
End Sub
End Class
But it threw the same error.
Ehhhhh, when exactely can I set the control's text?
Did I make any beginner's mistake?
Don't delete what the designer does :) It's trying to help you. When you Create the
Public Sub New(...)
on a form, it will automatically put in :
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
The InitializeComponent() is required to get the form ready for you to work with it.
Looks like you are missing the InitializeComponents call:
Public Sub New(ByVal uWindowText As String, ByVal uInfoText As String)
InitializeComponents()
m_sWindowText = uWindowText
m_sInfoText = uInfoText
End Sub
The method call loads all of the controls that were created using the designer. Without that call, your form is empty.

Using Generic List(Of Form), Trouble gathering Object's Name Property

I have been very interested as of late in interfaces and the ability to further customize them beyond using them in their default state.
I have been researching IList(of T) specifically. The advantages of using generic lists as opposed to ArrayLists has astounded me. Here is a picture of a test. This is the site that goes into further explanation about the Test.
So, naturally I wanted to experiment. When I first iterate through the list with the ForNext method the code works fine. The second time I can't access the name of the Form in the list because it is disposed. Anyone have any insight how I can access the forms properties in the list.
Public Class frmMain
Dim Cabinet As List(Of Form) = New List(Of Form)
Dim FormA As New Form1
Dim FormB As New Form2
Dim FormC As New Form3
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles _Me.Load
Cabinet.Add(FormA)
Cabinet.Add(FormB)
Cabinet.Add(FormC)
End Sub
Sub displayForm(ByVal aForm As Form)
Dim myFormName As String = ""
Stopwatch.Start()
If aForm.IsDisposed = False Then
aForm.Show()
Else
myFormName = aForm.(How do I access this objects Name?)
aForm = New Form '<----- I would rather simply use aForm = New(aForm)
aForm.Name = myFormName
aForm.Show()
End If
Stopwatch.Stop()
Dim RealResult As Decimal = (Stopwatch.ElapsedMilliseconds / 1000)
Debug.WriteLine(RealResult)
Stopwatch.Reset()
End Sub
Private Sub btnForEach_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnForEach.Click
'Dim instance as List
'Dim action as Action(of T)
'instance.ForEach(action)
'action = delegate to a method that performs an action on the object passeed to it
Cabinet.ForEach(AddressOf displayForm)
End Sub
I really don't understand why if VB knows that this is a Generic list, which means it is knowledgable of the list's type, and the objects are all constrained to be forms; why I can't call a constructor on an item in the list. Ex. aForm = New aForm or aForm = New Cabinet.aForm
Tear this one open for me somebody. Thanks.
You can't construct a new instance of "aForm" because its isn't a type, it is an instance of type Form.
If you wanted to prevent the ObjectDisposedException, you could hide the form instead of closing it. Place the following code in each forms code behind:
Public Class Form1
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
Dim form = CType(sender, Form)
form.Visible = False
e.Cancel = True
End Sub
End Class
This is a bit hacky, however, but then you wouldn't need the code in the Else block.
Edit
You could try this instead:
Private Sub displayForm(ByVal aForm As Form)
Dim indexOfCab As Integer = Cabinet.IndexOf(aForm)
If indexOfCab <> -1 Then
If aForm.IsDisposed Then
aForm = CreateForm(aForm.GetType())
Cabinet(indexOfCab) = aForm
End If
aForm.Show()
End If
End Sub
Private Shared Function CreateForm(formType As Type) As Form
Return CType(Activator.CreateInstance(formType), Form)
End Function
You wouldn't need that big Select statement.
This is the only way I have been able to get it to work. I feel it is extremely inefficient however, and hope someone can set me on a path to a better way to do this. The below is what I'm trying to achieve.
Sub displayForm(ByVal aForm As Form)
Dim myFormName As String = ""
If Cabinet.Contains(aForm) Then
Dim indexOfCab As Integer = Cabinet.IndexOf(aForm)
Dim ObjForm As Form = Cabinet.Item(indexOfCab)
If aForm.IsDisposed Then
Select Case indexOfCab
Case 0
aForm = Nothing
aForm = New Form1
Cabinet.Item(indexOfCab) = aForm
Cabinet.Item(indexOfCab).Show()
Case 1
aForm = Nothing
aForm = New Form2
Cabinet.Item(indexOfCab) = aForm
aForm.Show()
Case 2
aForm = Nothing
aForm = New Form3
Cabinet.Item(indexOfCab) = aForm
Cabinet.Item(indexOfCab).Show()
End Select
Else
Cabinet.Item(indexOfCab).Show()
End If
End If
End Sub