Hey guys I have got to a head scratcher well at least for me any way. I need to find a way of opening a form with a string. I have got this ...
Dim asm = System.Reflection.Assembly.GetExecutingAssembly
Dim myTypes As Type() = asm.GetTypes()
Dim frm As Form
For Each t As Type In myTypes
If t.IsSubclassOf(GetType(System.Windows.Forms.Form)) AndAlso Me.Label4.Text = t.Name Then
frm = CType(Activator.CreateInstance(t), Form)
frm.Close()
frm.Hide()
End If
Next
But it doesn't close the program or even hide it i have no clue?
Question: "I need to find a way of opening a form with a string"
Thanks in advance.
That looks to me like you created a new form instance of that type and tried to close/hide it, but I don't see it ever being shown.
If you are trying to close an existing form, then you don't want to create a new instance using Activator.CreateInstance. Rather you need to somehow locate the existing instance of the form that is already open, and close that specific instance.
The code you posted approximates code that would create a new instance of a form by type name, then close/hide the form.
(If you wanted to close an already-open form by name, I would do:
For Each f As Form In My.Application.OpenForms
If f Is My.Forms.NameOfFormThatIWantToClose Then f.Close()
Exit For
)
But I thought you wanted to open a new form by name. If so, you will need to use reflection. This page seems to do exactly what you want.
Related
I know this has been answered many times over and I am actually using code that seems to be working but I can't seem to get the actually data to be presented in the receiving form.
In the sending form I am select an item in a tree menu which triggers an event to open the receiving form and then pass the data. I put a break point in my receiving code and can see the data is applied to the variable. I applied that variable to text box but it does not appear on the open form.
Here is the code from the sending form. I am first checking to see if the form is open. My variable that I am passing is a string strControl.
If Application.OpenForms.OfType(Of Guidance_Info).Any() Then
Dim f1 As New Guidance_Info()
Guidance_Info.LoadGuidance_Info(strControl)
Else
Dim f1 As New Guidance_Info()
Guidance_Info.LoadGuidance_Info(strControl)
f1.Show()
End If
Here is the code from the receiving form. I first apply the variable to the table adapter, then a text box and then a message box. The only item that presents the data is the message box. Using a breakpoint I can see that the variable is being passed to the both the text box and the table adapter.
Friend Sub LoadGuidance_Info(ByVal ControlID As String)
Me._800_53_CtrlTableAdapter.FillByControl(Me.AssessGuidanceDataSet1._800_53_Ctrl,
ControlID)
Me.lblControl.Text = ControlID
MsgBox(ControlID)
End Sub
As you can see from this image the variable is receive properly:
Friend sub LoadGuidance_Info
I also tried using f1.ShowDialog() instead of f1.Show() but got the same results. The problem with the Dialog, you can't use the sending form until you close the receiving form.
Any help would be appreciated:
Your problem has nothing to do with passing data, but what you are passing it to.
You look for an open form instance but whether you find one or not, you create a New form instance, pass the data to a default form instance, then show the (New) form instance you created. In the end you have as many as 3 instances of the same form:
' first instance may be in the collection
If Application.OpenForms.OfType(Of Guidance_Info).Any() Then
...similar issue to below
Else
' create a NEW instance (#2)
Dim f1 As New Guidance_Info()
' use/create a default instance
Guidance_Info.LoadGuidance_Info(strControl)
' show #2
f1.Show()
End If
Neither #2 nor #3 can ever be the one that may be showing. Rather than just checking the collection for an instance, get it and check that (using more idiomatic naming):
Dim f1 = Application.OpenForms.OfType(Of GuidanceInfo)().FirstOrDefault
If f1 IsNot Nothing Then
' use existing
f1.LoadInfo(strControl)
Else
' create, update, show one new form instance
f1 = New GuidanceInfo()
f1.LoadInfo(strControl)
f1.Show()
End If
I have an application with several forms(frm1, frm2...). Under each form there is a sub method: sub1. Is that possible to create a method in module to get all opened forms and made then run frm1.sub1, frm2.sub1...?
I already know that My.Application.OpenForms can find all opened form. But how to use this for next step? Since there are bunch of forms I can't name the form like this one by one.
'$'
Dim frm As Form
For Each frm In My.Application.OpenForms
If frm Is My.Forms.TheFormINeed Then
'do something
end if
This may sounds newbie. Please help me.
If all the subs you want to run are present in all the forms, then
For Each frm In My.Application.OpenForms
CallByName(frm, "sub1", CallType.Method, Nothing)
Next
should do the trick.
Bear in mind of course that your main form may not have the sub, so you can use If..Then etc to include or exclude particular forms of course.
You can name forms by the way by setting the.Name property
I am building an application using one of our vendors interfaces, which is required to keep a status message box updated.
I have some events which I have handled for testing using a Message box, but now I come to pass these messages to the display box I get nothing.
Public Shared Sub PageAirHandler(ChannelNum As Integer, Index As Integer, ChannelType As CLARITYCOMLib.ChannelType, PageName As String) Handles Status1.AirStatusChanged
MessageBox.Show(PageName)
ControlPanel.AirStatusBox.Text = PageName
End Sub
The messagebox dutifully displays the PageName string, but the textbox does nothing... even if I replace the PageName String variable with "test"
ControlPanel.AirStatusBox.Text = "test"
I get no activity, no errors, nada.
I have googled around, but every example I can find seems to show the same code.
I have recreated the textbox, tried buttons, labels and other objects with the same result.
Setting up a button click handler to update any of these works as expected.
Apologies if this is a noob blunder, but it's driving me nuts!
Using dlg As New Form2
dlg.ShowDialog()
End Using
Things like:
Form2.Show()
Form2.Show(Me)
Form2.ShowDialog()
Form2.ShowDialog(Me)
SHOUL BE AVOIDED but are possible, because Vb.net creates an implicit instance.
But the problem is, this instance gets killed if
the call has be done.
There you can see that a class instance of a project does not interact correctly
in some cases.
As Hans Passant said, your call to set the textbox text
targets the wrong instance.
Invoking to user controls is also possible with:
Me.invoke(sub()
TextBox1.Text = "Blabla"
End sub)
I am working on a project that has WebBrowsers in Other Forms;
I wrote the code below to control these WebBrowsers; but I need the code to recognize (Declare) the WebBrowsers of these forms.
Dim openForm As Form = Nothing
For Index As Integer = My.Application.OpenForms.Count - 1 To 0 Step -1
openForm = My.Application.OpenForms.Item(Index)
If openForm IsNot Me Then
MyWebBrowser.navigate("http://www.google.com/") ' PROBLEM IN THIS LINE
End If
Next
My Module created them as below:
Module MMMBrowser
Dim frmNew As New Form
Dim MekdamBrowser As New WebBrowser
Other info gleaned from comments:
there is form factory of some sort which creates new frmNew
there are many of these open at a time, which is the reason for the backwards loop thru OpenForms to find the last one.
The MekdamBrowser reference is an attempt to refer to the browser on the form.
The easy things is to provide a way for outsiders to tell the form to navigate somewhere using a new Sub, and let the form drive the browser control. This probably eliminates the need for a global MekdamBrowser reference. In the browser form add something like this:
Public Sub GotoNewURL(url As String)
myWebBrowserName.navigate(url)
End Sub
This procedure only exists for Form1 not the generic Form type, so we need to change how you find the form to use. Your existing loop is wonky. It will only ever find the last instance of a form which is not the current form. If you add a third form type, it wont work well:
Dim lastBrowserFrm As Form1 ' use the class name!
' this will try to get the last Instance of Form1
lastBrowserFrm = Application.OpenForms.OfType(Of Form1)().LastOrDefault
' LastOrDefaultcan return nothing if there are none,
' so test
If lastBrowserFrm IsNot Nothing Then
lastBrowserFrm .GotoNewUrl("www.stackoverflow.com")
Else
' create a new one, I guess
End If
Your loop was not considering that there could be other form types in the collection which are not Form1 or even if a new browser form was the last one created! This is more important now because GotoNewURL is only available on Form1 instances.
I changed the name to lastBrowserFrm to reflect what is really going one - it will just find the last one created. If you are trying to work with a specific instance, you need to provide a way to track the ones you create such as with a List(of Form1) or use the Name property so you can tell one from the other. As is, you do not a way to get back a specific form instance.
Throughout our program, forms are opened like this:
FormName.SomeValue = 10
FormName.ShowDialog()
rather than the usual
Dim myForm As New FormName
myForm.SomeValue = 10
myForm.ShowDialog()
(There is nothing we could do about this - this was done automatically by the Visual Studio VB6 --> VB.Net converter)
The problem is that when forms are closed, they seem to not really be closed, only hidden - if I add some text to a textbox and close/reopen the form, the text is still there, rather than the textbox being cleared like normal. This is presumably because the form always uses the same instance.
Is there any easy way to fix this other than going through the entire program and creating a new form instance for every ShowDialog() call (there are hundreds)?
We considered resetting every control in every form's Load event, but that would still be a pain, so we figured we'd ask if there's a simpler way first.
public class MyForm: Form{
private static MyForm myForm = null;
public static DialogResult ShowDialog(bool newForm){
if(newForm)
{
if(myForm != null)
myForm.Dispose();
myForm= new MyForm();
}
return myForm.ShowDialog();
}
public static DialogResult ShowDialog(){
return ShowDialog(true);
}
}
What you are dealing with is called the form's "default instance" and is a carry over from the VB6 days. It is not recommended practice to use it. You may not want to hear it, but the best long-term strategy for your code base is to rewrite the form initializers the correct way than to do some hacky workaround in the form Load() events. You may hate it now, but you will appreciate it the next time you have to work on this code. You can probably even put together a snippet to do most of the typing for you.
Edit:
How to display the form using the Using statement
Using formName AS New FormName
formName.SomeValue = 10
formName.ShowDialog()
End Using
It appears from the code displayed here that there is now a static ShowDialog call that was added to your FormName class. You should be able to edit just this method to dispose of the old form and create and display the new one. This would help you avoid changing code all over the place, just in the one location.
You asked for easy way to fix this:
Change your ShowDialog() procedure/function calls in the following way:
AS PROCEDURE | AS FUNCTION
|
FormName.ShowDialog() | r = FormName.ShowDialog()
FormName.ShowDialog() | r = FormName.ShowDialog()
|
CHANGE TO | CHANGE TO
|
Call New FormName.ShowDialog() | r = New FormName.ShowDialog()
Call New FormName.ShowDialog() | r = New FormName.ShowDialog()
I know this is super late but-
Form1.Dispose()
works for me. It resets the textboxes.
If the question is about clearing text boxes then I would have Cleared all of them RECURSIVELY
For Each Control in Controls
If Control is type of TextBox
Control.Clear
Next
If you are binding controls by any DATASOURCE I would suggest to clear the Datasource and REBIND
Override the ShowDialog() Method.