For simple communication between forms, the VB6.0 method can meet our requirements. However, in some complicated architecture design applications, this method is a little too slow, at the same time, this method also has a disadvantage, that is, it only applies to pass. the form added by the. NET Form Wizard takes effect, but the custom form type cannot be added to the Forms object set. In addition, like other methods such as constructor parameter passing, they will reference their members in a large number of forms, resulting in great coupling between them, it is not conducive to the independence of form modules, which is not in line with the idea of a good software design model.
If we want to access a custom member in another form, we must set the Member's visibility to Public or make the member Public through the attribute. If we want to access the custom member in another form, we can still say that the member is made Public through the attribute, but if you set the visibility to Public, this will inevitably undermine the type encapsulation principle, and this approach is also in our. NET development is quite happy, especially for initial contact. NET developers first think of setting the Member's visibility to Public when accessing another type of members. Of course, this is not an error, however, it is obviously inappropriate to take this approach as the primary inspiration, at least from the object-oriented perspective.
In. NET, another powerful mechanism is provided for us to implement form communication. This is the delegate. Delegation can be understood as a type of safe function pointer. The implementation of events in. NET is based on delegation. I will not introduce delegation in detail in this article. Later I will introduce this concept in detail. In this example, we add an Item to The ListBox control in another form to describe this method. Therefore, two forms, one MainFrm form and one ChildFrm form are required. In addition, a Middle class is required to serve as a bridge between MainFrm and ChildFrm. I will also provide the code for VB. NET and C #, so that you can make a comparison.
The first is the MainFrm form. In the MainFrm form, drag a ListBox control. The MainFrm. vb Code is as follows (for simplicity, the automatically generated code is omitted here ):
Public Class Form3
Private Sub Form3_Load (ByVal sender As System. Object, ByVal e As System. EventArgs) Handles MyBase. Load
AddHandler Middle. SendMessage, AddressOf DoMethod
End Sub
Private Sub DoMethod (ByVal getstr As String)
Me. ListBox1.Items. Add (getstr)
End Sub
End Class
Let's look at the ChildFrm form. Drag a TextBox and a Button control to it. After entering a value in the TextBox, press the Button to add an Item to the ListBox control of the MainFrm form.
Public Class Form2
Private Sub Button1_Click_1 (ByVal sender As System. Object, ByVal e As System. EventArgs) Handles Button1.Click
Middle. DoSendMessage (TextBox1.Text)
TextBox1.Text = ""
TextBox1.Focus ()
End Sub
End Class
Finally, let's look at the Middle class:
Public Class Middle
Public Shared Event SendMessage (ByVal str As String)
Public Shared Sub DoSendMessage (ByVal str As String)
RaiseEvent SendMessage (str)
End Sub
End Class
To better demonstrate the independence between MainFrm and ChildFrm, modify the Application. Designer. vb code:
<Global. System. Diagnostics. DebuggerStepThroughAttribute ()>
Protected Overrides Sub OnCreateMainForm ()
Me. MainForm = Global. WindowsApplication3.MainFrm
ChildFrm. show ()
End Sub
Okay, the code is complete, isn't it easy? The code above shows that, through the Middle class, MainFrm and ChildFrm communicate with the Middle class, they no longer reference internal members of each other except parameter coupling, this makes it more independent.
Below is the corresponding C # code, MainFrm. cs:
Public partial class MainFrm: Form
{
Private void MainFrm _ Load (object sender, EventArgs e)
{
Middle. sendEvent + = new Middle. SendMessage (this. DoMethod );
}
Public void DoMethod (string getstr)
{
ListBox1.Items. Add (getstr );
}
}
ChildFrm. cs:
Public partial class ChildFrm: Form
{
Public ChildFrm ()
{
InitializeComponent ();
}
Private void button#click (object sender, EventArgs e)
{
Middle. DoSendMessage (this. textBox1.Text );
TextBox1.Text = "";
TextBox1.Focus ();
}
}
Middle. cs:
Public static class Middle
{
Public delegate void SendMessage (string str );
Public static event SendMessage sendEvent;
Public static void DoSendMessage (string str)
{
SendEvent (str );
}
}
Let's also modify the code of Program. cs:
Static class Program
{
[STAThread]
Static void Main ()
{
Application. EnableVisualStyles ();
Application. SetCompatibleTextRenderingDefault (false );
// Application. Run (new Form1 ());
Form1 mainFrm = new Form1 ();
ChildFrm secondFrm = new childFrm ();
SecondFrm. Show ();
Application. Run (mainFrm );
}
}
Compare the preceding VB. NET and C # code, we can see that VB. NET allows the Event to be declared directly with the Event keyword, while C # must first declare the Event's delegate prototype and then declare the Event based on the delegate. From this point of view, VB. NET is more concise, in fact, VB. NET compiler automatically defines a delegate object for us, and the delegate is the same as the IL code generated by the delegate declared by C # code, you can view this point through the Ildasm intermediate code viewer. Event, VB. NET adds the event name through the RaiseEvent keyword, while C # directly uses the event name. Finally, it binds the Event code, VB. NET is through the AddHandler keyword, C # Through the overloaded + = Operator, for the above two points, the compiler will also generate consistent IL code for us.
Of course, the above example is relatively simple, but we can implement complex form communication through delegation. For example, we can transmit complex data types, and at the same time, we can design intermediate Communication classes with better structures. However, we should also remind you not to use delegation unless you do not move. It will increase the complexity of the program, and you should consider the method based on your own needs.