Make Progress Bar Running From Public Class

2019-08-28 00:40发布

问题:

I have create a form with Object like Progress bar and button. I have create also public library code outside my form

My question is : I want to modify the progress bar or the text button from a Sub that is written in a library (I try to pass my form as a parameter):

Public Shared Sub ModifyItems(ByRef _WhichForm As Form)<br>
   _WhichForm.MyProgressBar1.visible = true<br>
End sub<br>

Unfortunately, the code Is not recognizing my progress bar name : MyProgressBar1

Is there a way to modify my progress bar on my form directly in a Sub or function that is written in a class library, not directly in the form code ?

回答1:

This type of approach would generally fall under the umbrella of "bad practice". Having objects modifying each others members directly introduces tight coupling that makes for difficult code to extend, debug, and maintain.

Rather than trying to modify something from within the library, better to think in terms of notifying that something within the library has changed. You could, for example, raise an event within the library. Form1 could then listen for that event and make any changes to its components that are appropriate. This way Form1 is solely responsible for modifying its components and the library is solely responsible for announcing changes to its internal state.

To give a good example - if, say, you were to change your Form's progress bar component (maybe you find a better one out there) you suddenly introduce a breaking change into your library.

To use an event you might do something like :

Public Class MyLibrary
    Event OnSomethingHappened()

    Private Sub SomethingHappened()
       RaiseEvent OnSomethingHappened()
    End Sub
End Class

And then in your form :

Public Class Form1
    Private WithEvents _myLibrary as New MyLibrary

    Private Sub LibraryDidSomething() Handles _myLibrary.OnSomethingHappened
        MyProgressBar1.Visible = True
    End Sub
End Class

This nicely decouples any dependence on Form1 - the library exists as a self-contained entity and doesn't care who listens to its events.

If you want to do this with a shared class you can also use shared events - these must be connected programmatically as :

Public Class MyLibrary
    Shared Event OnSomething()

    Public Shared Sub DoSomething()
        RaiseEvent OnSomething()
    End Sub
End Class

in the form :

Public Class Form1
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) _
                                                        Handles MyBase.Load
       AddHandler MyLibrary.OnSomethingHappened, AddressOf LibDidSomething
    End Sub

    Private Sub Form1_FormClosed(sender As System.Object, e As _
        System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
       RemoveHandler MyLibrary.OnSomethingHappened, AddressOf LibDidSomething
    End Sub

    Private Sub LibDidSomething() 
        MyProgressBar1.Visible = True
    End Sub
End Class

When programmatically adding events you must take care to remove them before disposing of the objects that have subscribed to them. In this case I have added the handler when the form loads and have removed it when the form closes. If you fail to remove an added handler then the form would not be garbage collected and this would cause a memory leak.

See here for more reading : Raising Events and Responding to Events (MSDN)