Using button.enabled outside the Button_Click sub - vb.net

I am just starting out with Visual basic .Net. I am designing an application where each button should disable itself after a registering a single click on it.
I am trying to add an additional sub, which when called, disables all of the buttons. (Disable_all())
Public Sub disable_all()
MsgBox("Testing disable_all")
Button_eight.Enabled = False
End Sub
One of the subs is calling it from the main module.
Private Sub disable()
Dim variab As Form1 = New Form1
variab.disable_all()
End Sub
The disable_all() sub however does not disable Button_eight when called. I placed a message box to check if the sub (disable_all) is getting executed, which it is. I get a message box having the text "Testing disable all" but the Button_eight is not disabled for some weird reason.
I'd really appreciate some help, thanks.

It's simple, just do Form1.disable_all().
That is, instead of variab.disable_all(), call: form1.disable_all() from the main module. Because as mentioned in the comments, new form1 creates a new instance of Form1.
You can also create a variable that point to the form dim var = form1 or dim variab as form = form1, but since you can access form1 directly from your module, it is unnecessary.

Related

vb.net a forms "new" routine is being called before I even invoke the form

I have a form called "partmanager". On it is a button to show another form "parteditor" to allow editing details of a part. Clicking that button will show the form and pass in a variable to the parteditors "new" routine.
My problem is that when the calling form (partmanager) starts, it immediately calls new routine in the parteditor form before it (partmanager) is even initialized so the parteditor form does not get the string that is supposed to be passed in. Later, when the calling form is visible and I click the button to show the parteditor form, new has already been prematurely called and so is not called again and the form does not get the string passed in.
I hope this makes sense!
I can implement a property in the parteditor form and pass in my variable that way prior to showing the form and that will work, thereby not even requiring a "new" routine in the parteditor forms code.
So my question is, is implementing the property the proper way to pass this variable to the form being called, or am I not properly coding my forms? (I also have an intermediary module called "commands" where I have been defining command procedures, in this case just showing a form.)
any pointers would be appreciated, thanks!
here is the code for the button in the calling form:
Private Sub EditButton_Click(sender As Object, e As EventArgs) Handles EditButton.Click
Commands.EditPart(_PartNumber) 'call the editpart command
Me.Close()
Me.Dispose()
End Sub
here is the code for the form being called:
Public Class PartEditForm
Private _partNumber As String = String.Empty
Public Sub New(partNumber As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_partNumber = partNumber
End Sub
Private Sub PartEditForm_Load(sender As Object, e As EventArgs) Handles Me.Load
Label1.Text = _partNumber
End Sub
End Class
and here is the code in my "commands" module for loading/showing the form:
Public PartEditForm As New PartEditForm(_partNumber)
Public Sub EditPart(partnumber As String)
If PartEditForm.IsDisposed Then
PartEditForm = New PartEditForm(partnumber)
End If
PartEditForm.Show()
End Sub
you can save the routine in a dim variable and get this on the other form and close the first form or hide but you need get in new var and contine where stop before.

Control event not firing in a VBA Class Module

I have a problem getting any event firing from controls embedded in Class Modules in VBA Access. Despite many (many!) conversations in various forums related to this one, I haven't found any that help me. As far as I can tell I am following all their advices (mainly, I always use "Access.Control", "Access.Label" and so on so it is always the same library that is used, and the reference still exists at the moment the event should fire...), but it still doesn't fire!
In the same project I have the same problem in several classes; I will take the example of a group of labels on a form.
The load event of the form creates a first, big group like that:
Private Sub Form_Load()
...
set mGroups = new CDocTree
mGroups.Make Me
End Sub
In CDocTree there are three member variables declared like that:
Private WithEvents mVVPlan As CDocGroup
Private WithEvents mTestPlan As CDocGroup
Private mFrm As Form_FrmAlphaDocuments
and the method Make essentially does this:
Public Sub Make(frm As Access.Form)
Set mFrm = frm
With mFrm
Set mVVPlan = New CDocGroup
mVVPlan .Make .LblVVPlanBox, .LblVVPlanRef
Set mTestPlan = New CDocGroup
mTestPlan .Make .LblTestPlanBox, .LblTestPlanRef
End With
End Sub
Finally the class CDocGroup is defined like that:
Private WithEvents mBox As Access.Label
Private WithEvents mRef As Access.Label
Public Event Clicked(grp As CDocGroup)
Public Sub Make(box As Access.Label, ref As Access.Label)
...
Set mBox = box
Set mRef = ref
End Sub
Private Sub mBox_Click()
Debug.Print "Event Click fired in CDocGroup on " & mBox.Name
RaiseEvent Clicked(Me)
End Sub
Private Sub mRef_Click()
Debug.Print "Event Click fired in CDocGroup on " & mRef.Name
RaiseEvent Clicked(Me)
End Sub
That's it: the code never gets in mBox_Click or mRef_Click. What do I do wrong?
Thanks VBlades, it does the trick.
Although it is infuriating that something like this should be necessary, I can indeed verify that if I put a declaration for some of the controls and not for others, my events fire only for the controls that have the empty event declaration in the form's module.
So to be clear, in the form's module, for each control that I need to react, I add an empty declaration:
Private Sub LblVVPlanBox_Click()
End Sub
No code at all in it, but now the event in my class fires and the code in the class is executed. It is kind of ugly, but still better than copying 20 times the same instructions in the form's module.
If anybody comes across this post like me, trying to figure out why the events aren't firing, there is a far simpler solution on another forum.
Basically when you set your mBox / mRef in the class module do the following:
mBox.OnClick = "[Event Procedure]"
mRef.OnClick = "[Event Procedure]"
This will let the class module know, that there is an event it has to execute. So there is no need to declare all the subs in your forms code.

Accessing text box on Form1 from Form2

I am new to vb.net so forgive me if this is an easy question.
I have a created a class library project that houses two windows forms, Form1 and Form2. The main class library has the event to open Form1. A button on Form1 launches Form2. The bulk of the code is in Form1, which I don't want to change if I can help it.
What I am trying to do, is access a sub that is on Form1 from Form2. That sub is changing the value of a text box on Form 1. I don't get any errors when I compile the project, however, nothing happens.
Here is an example
Form1:
Public Sub test()
Me.Panel1.Controls("Textbox1").Text = "Test"
End Sub
Form2:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim MainForm As New Form1
Me.Close()
MainForm.test()
End Sub
Don't get too caught up on how I built it out, I have tried about 20 different things and this is where I am at now.
I have tried defining Form1 in the sub test(). I have tried setting sub test() to shared. I have tried closing Form2 and activating Form1. I have tried changing the modifiers property on the text box to public. I have tried making Form1 the parent and Form2 a child (I honestly don't understand MDI very much). All these results end up in a project that will compile but wont give me any results. My code accesses the sub just fine, it wont access the text box's text property.
Any suggestions will help. I am trying to access the text boxes in a way that I can loop through all of them. For example: Me.Panel.Controls("Textbox" & i).Text = "Something". Also I would like to keep the sub in the class for Form1 if I can.
Any suggestions would be great!
You are creating a brand new Form1 in Form2, that is the problem.
Just use :
Call Form1.test()
By the way, I think this code in the sub is an easier way to set the text:
Panel1.TextBox1.Text = "Test"

Delegates not working in another module

Running into an odd issue with tasks and delegates. Code in question is running under dotNET 4.5.1, VS2013. On the form's code I have a sub that updates a grid, it checks to see if an invoke is required, and if it is it calls a delegate. When a task runs that's called in the same module, it works as expected, no problems. Threaded or not, the grid updates properly.
However, if the same thing is called from another module, the delegate never gets called and the visual component doesn't get updated. Just a watered down bit of pseudocode to clarify..
In the form's module:
Private Delegate Sub DoWhateverDelegate(ByVal _____)
Public Sub DoWhatever(ByVal _____)
If MyComponent.InvokeReqired
Dim Delegated As New DoWhateverDelegate(AddressOf DoWhatever)
Debug.Print("The delegate fired")
Invoke(Delegated, _____)
Else
' .. carry on as usual ..
End If
End Sub
Elsewhere....
Task.Run(Sub()
' .. various things I'd rather not block the UI thread with ..
DoWhatever()
End Sub)
Works fine. I can do Task.Run__ that calls DoWhatever and it's all happy and good. However if I create a task in another module and call DoWhatever, it doesn't fire the delegate and that visual component doesn't update. The code is identical, in the same module it works, in another module it does not.
I'm probably missing something blatantly obvious.. anyone care to point out my mistake? Thanks.
Edit -- just to clarify, that other module is just code, there's only one form in the entire solution. It's created at program startup automatically, there is no other form creation going on.
Should be a thread-specific issue. Check this:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
foo.DoSomething()
End Sub
End Class
The class with the delegate:
Public Class foo
Public Shared Sub DoSomething()
Task.Run(Sub() UpdateText())
End Sub
Public Delegate Sub UpdateTextDelegate()
Public Shared Sub UpdateText()
Dim f = Form1
'Dim f As Form1 = Application.OpenForms("Form1")
If f.InvokeRequired Then
Dim d As UpdateTextDelegate = AddressOf UpdateText
f.Invoke(d)
Else
f.TextBox1.Text = "Hi"
End If
End Sub
End Class
Run the code and the textbox will not be updated. Use the second f=.... (that one that take a reference from OpenForms) and it will be updated.
If you just try to access the default instance and you are outside the UI-thread, a new instance of the form will be created. That means, the content IS updated, but because that form is not shown, you will not see it.
NOTE I do NOT advise to solve your problem, by using OpenForms. I'd advise to correctly instantiate forms!
Add a new module/class to your code:
Module Startup
Public MyForm1 As Form1
Public Sub main()
MyForm1 = New Form1
Application.Run(MyForm1)
End Sub
End Module
Go to project properties -> application. Disable application framework and choose Sub Main as your start object. In the app, access your form via MyForm1 - or whatever you want to name it. Problem should be gone then.

VB.net - Derived class from MenuStrip

What I am trying to do is make a custom MenuStrip control with several items (Main Menu, Log Out, Exit, etc...) already attached. There would be methods to handle items being clicked. I think this would save me a some redundant code in the long run and I might learn a little something too.
The end product would basically be a custom MenuStrip control that I can throw on my forms and already have the functionality for the items within it.
So my question is, can this be done? I am a novice but if it can be done and is actually a good idea, then I want give it a shot.
Errors abound but this is what I was thinking...
Public Class MenuStripCustom
Inherits MenuStrip
Add MenuItem(MainMenuToolStripMenuItem)
MainMenuToolStripMenuItem.Text = Main Menu
Protected Sub MainMenuNav(e As System.EventArgs) _
Handles MyBase.MainMenuToolStripMenuItem.Click
MainMenu.Visible = True
Me.Close()
End Sub
End Class
Thanks!
Yes, can be done no problems. Just create a new user control, and make it inherit from MenuStrip. Then put in code similar to the below for a user control called "UserControl1".
Public Class UserControl1
Inherits MenuStrip
Private WithEvents NavToolStrip As New ToolStripMenuItem("Nav")
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Dim tsi As New ToolStripMenuItem
Me.Items.Add(NavToolStrip)
End Sub
Private Sub NavToolStrip_Click(sender As Object, e As EventArgs) Handles NavToolStrip.Click
MsgBox("Nav clicked")
End Sub
End Class
Compile the code then you will be able to drag "UserControl1" from your toolbox onto your form.