Easily master data interaction between Windows forms
Author: Zheng Zuo 2004-04-05
The Windows Form is a new platform based on .NET Framework developed by Microsoft Windows applications. This framework provides a conditional, object-oriented, scalable class set that enables you to develop a wealth of Windows applications. A Windows Form represents an instance of the System.Windows.Forms.form class in the .NET architecture.
The author is in the 9CBS technology forum. NET sections often see someone asking how to deliver data between two FORMs, access the value inside the other party form. For those who have experienced programmers, it is not a deep thing. For beginners, these foundations are often a problem, and this phenomenon is often more complicated. They will learn. What is actually not really understanding it, the foundation is not solid, so I want to write some articles in this regard through my own experience of the form of the form, to give the school .NET friend reference, also borrowed This opportunity communicates with friends, please ask your friends to pay for usa, and I have divided into three parts.
One. Using parametric constructor we have to do prepared to build two forms, below is the layout of two forms, very simple:
Description: Form1 is the main form, contains controls: text box textboxfrm1, multi-selection box checkboxfrm1 and buttons ButtonEdit;
Form2 is a child form, contains control: text box textboxfrm2, multi-selection box checkboxfrm2 and buttons Buttonok, Buttoncancel.
When we create new forms, the designer generates the default constructor:
Public Form2 ()
{
InitializationComponent ();
}
It does not have parameters, since we have to pass some of the data in Form1 to FORM2, why not do an article in Form2 constructor?
Suppose we want to implement the text box in Form2 to display the value of the textboxfrm1 in Form1, modify the constructor of the child form:
Public Form2 (String text)
{
InitializationComponent ();
THIS.TEXTBOXFRM2.TEXT = TEXT;
}
Increase the modification button in FORM1, click the event, the process function is as follows:
Private void buttonEDit_click (Object Sender, System.Eventargs E)
{
Form2 formchild = new form2 (THISTEXTBOXFRM1.TEXT);
Formchild.show ();
}
We transmit this.textboxfrm1.text as a parameter to the child form constructor, in a non-mode mode, this open formchild's text box shows the "main form" text, is it very simple, then let's pass one Boolean data to the child form.
Public Form2 (String Text, Bool CheckedValue)
{
InitializationComponent ();
THIS.TEXTBOXFRM2.TEXT = TEXT;
This.checkboxfrm2.checked = checkedValue;
}
The modification button in the main form is clicked, I use the way to open the mode window, in this example, I can't see anything,
Private void buttonEDit_click (Object sender, system.eventargs e) {
Form2 formchild = new form2 (this.textboxfrm1.text, this.checkboxfrm1.checked);
Formchild.showdialog ();
}
The result is in the expected, but there is a significant shortcomings, and the main form cannot be transmitted after the data in the childfield, that is, the effect of the main form is not subject. In the actual development process, we often use the child form to modify the data in the main form, how to solve it?
There are two types, value types, and reference types in .NET. The value type is inherited from valueetype, and ValueType is inherited from Object; for reference type it directly inherits the Object type. Let us look at how to modify the data in Form1 through Form2.
Or let us modify the code of Form2.
Private textbox textboxfrm12;
Private checkbox checkboxfrm12;
Public Form2 (TextBox Heckbox, Checkbox Heckbox)
{
InitializationComponent ();
THIS.TEXTBOXFRM2.TEXT = Heckbo.Text;
This.checkboxfrm2.checked = heckbox.checked;
THIS.TEXTBOXFRM12 = Heckbo;
THIS.CHECKBOXFRM12 = Heckbox;
}
Now we have passed the data of two reference types: TextBox type, and checkbox; additional two class data member TextBoxFRM12 is added in Form2, and checkboxfrm12 is used to save the variables from constructor, but they do not belong to form2 Controls. container. Modify the FORM2 determination button Click the event function:
Private Void Buttonok_Click (Object Sender, System.EventArgs E)
{
THIS.TEXTBOXFRM12.TEXT = this.TextBoxFrm2.Text;
THISCHECKBOXFRM12.CHECKED = this.checkboxfrm2.checked;
THIS.CLOSE ();
}
The above code we finish by textBoxFrm2 of Text and checkBoxFrm2.Checked assigned textBoxFrm12 and checkBoxFrm12 modifications to the main form of textBoxFrm1 and checkBoxFrm2 because textBoxFrm1 and textBoxFrm12 is the same references, and checkBoxFrm2 and checkBoxFrm12 too.
The function is achieved here, but I always feel that it is not very reasonable, let the two form controls come back, now I will give an appropriate example.
Modified two forms:
Note: In this example, our two forms have added a listbox to display content in ArrayList.
Controls in main forms: ListBoxfrm1, buttonedit;
Subform control: Listboxfrm2, TextBoxAdd, Buttonadd, Buttonedit, Buttonok.
This time we use ArrayList as transfer data, define class data members in Form1:
Private arraylist listdata1;
In the constructor, the memory allocation is added to the ListData1, and the generated data is finally bound to listboxfrm1, public form1 ()
{
InitializationComponent ();
THISTDATA1 = New ArrayList ();
This.ListData1.Add ("DOTNET");
THISTDATA1.ADD ("C #");
This.ListData1.Add ("ASP.NET");
THISLISTDATA1.ADD ("WebService");
This.ListData1.Add ("XML");
this.listboxfrm1.datasource = this.listdata1;
}
In addition, the modification of the event handler for the modification button is as follows:
Private void buttonEDit_click (Object Sender, System.Eventargs E)
{
Form2 formchild = new form2 (this.listdata1);
Formchild.showdialog ();
THISTBOXFRM1.DATASOURCE = NULL;
this.listboxfrm1.datasource = this.listdata1;
}
Relative to the main form, the child form is modified accordingly, and the class data member is also added in Form2:
Private arraylist listdata2;
Use to save the reference to ListData1 in the main form.
Modify constructor:
PUBLIC FORM2 (ArrayList ListData)
{
InitializationComponent ();
THISTDATA2 = ListData;
Foreach (Object O in this.listdata2)
{
This.ListBoxfrm2.Items.Add (O);
}
}
Here, ListData2 is pointing to the same reference with ListData1; there is no binding of ListBoxFRM and padding.
Ok, the following is the time to operate.
The additive function code is as follows:
Private void ButtonAdd_click (Object Sender, System.EventArgs E)
{
IF (THIS.TEXTBOXADD.TEXT.TRIM (). Length> 0)
{
This.ListData2.add (this.TextBoxAdd.Text.trim ());
This.ListBoxfrm2.Items.add (this.TextBoxAdd.Text.trim ());
}
Else
MessageBox.show ("Please enter the added content!");
}
The delete processing code is as follows:
Private void buttonDel_click (Object Sender, System.EventArgs E)
{
INDEX = this.listboxfrm2.selectedIndIndex;
IF (INDEX! = - 1)
{
This.ListData2.removeat (INDEX);
This.ListBoxfrm2.Items.Removeat (Index);
}
Else
MessageBox.show ("Please select the delete item or there is no delete item!");
}
Exit the Form2 subform:
Private Void Buttonok_Click (Object Sender, System.EventArgs E)
{
THIS.CLOSE ();
}
The compiler is modified to the data in the child form, and the main form will display the updated data.
Here is something to remind, compare two examples, we all pass the reference type, one is string, the other is ArrayList, why cannot modify the main form of the STRING? In fact, the modification of the String type in .NET is not modified by the original value. The original value has not changed, but regenerates a new string, which is a good description.
Public Class Zzconsole
{
[Stathread]
Static void main (string [] args)
{
String str1 = "abc";
String str2 = STR1;
STR1 = "123";
Console.writeLine (STR1);
Console.writeline ("------------");
Console.writeLine (STR2);
Console.writeline ("------------");
ArrayList al1 = new arraylist ();
Al1.Add ("abc");
ArrayList Al2 = AL1;
Al2.Add ("123");
Foreach (Object O IN AL1)
Console.writeline (String) O);
Console.writeline ("------------");
Foreach (Object O IN AL2)
Console.writeline (String) O);
Console.readline ();
}
}
When you run, look at the output results, additional data operations for value types To use the REF keyword.
Summary, we have implemented the data interaction between the forms through the constructor of the parameters, and the code looks more clear. In the actual development process, you can use DataSet, DataTable, or DataView as a parameter. Of course, if just want to modify a line. You can pass a DATAROW or DATAROWVIEW.
two. Add attributes or methods to forms
1. Use the Owner property of the FORM class
Gets or sets a form that has this form. To make a form return to another form, assign a reference to its OWNER attribute to become a form of a form that will become the owner. When a form is hosted by another form, it minimizes and closes the owner form. For example, if the Form2 is returned to the form FORM1, it is turned off or minimized when the FORM1 is turned off or minimized. And the accessory form is never displayed behind the owner form. The accessory form can be used to find and replace the window, and these windows should not disappear when the owner form is selected. To determine the form owned by a parent form, use the OwNedForms property.
The above is the SDK help document, let's use it below.
First, use the second example in the first article, the form is as follows: Description: In this example, our two forms add a listbox to display the contents of ArrayList. Controls in the main form: ListBoxFRM1, Buttonedit; Subform Control: Listboxfrm2, TextBoxAdd, Buttonadd, ButtonEdit, Buttonok. The main form is or defined by a class data member, and the private arraylist listdata1; instantiates it in the constructor, fill the data, and finally bound to ListBoxFRM1. The constructor is as follows: public form1 () {INITIALIZECMPONENT (); this.listdata1 = new arraylist (); this.listdata1.add ("dotnet"); this.listdata1.add ("c #"); this.listdata1.add "ASP.NET"); this.listdata1.add ("Webservice"); this.listdata1.add ("xml"); this.listboxfrm1.datasource = this.listdata1;} Master's modification button processing function: private void buttonEdit_Click (object sender, System.EventArgs e) {Form2 formChild = new Form2 (); formChild.Owner = this; formChild.ShowDialog (); this.listBoxFrm1.DataSource = null; this.listBoxFrm1.DataSource = this.listData1; } We set formchild.owner as this, so that the sub-form and the main form are connected, of course, we can also change to the following: private void button -dit_click (Object sender, system.eventargs e) {form2 formchild = New Form2 (); This); this); this.listboxfrm1.datasource = null; this.listboxfrm1.datasource = this.listdata1;} But not yet, the current ListData1 variable outside the main form is not available, private arraylist listdata1; Must be modified to access the modifier, public arrayli, PUBLIC ST ListData1; can also be implemented by properties, public arraylist listdata1 {get {return this.listdata1;}} Here I adopt attributes, feeling more flexible and clear. Below is a modification of FORM2, and the constructor is restored.
Public form2 () {initializationComponent (); additionally adds a form's LOAD event, in its event handler, get data in the main form, Private Void Form2_Load (Object Sender, System.EventArgs E) {Form1 Pareform = (Form1) this.owner; this.listdata2 = peach (Object O in this.listdata2) this.listboxfrm2.items.add (o);} Some people will ask, why not put the above code Place it in the constructor? The following is not better, public form2 () {INITIALIZECMOMPONENT (); Form1 Pareform = (Form1) this.owner; this.listdata2 = peach (Object O in this.listData2) this.listboxfrm2.Items.Add (O ); Then I will be wrong to you, because after the main form modification button is clicked, start executing form2 formchild = new form2 (); and executing Form1 Pareform in the constructor during the instantiation of Form2. (Form1) this.owner; at this time, this.owner is no value, is an empty reference, then the following code is definitely problem, this.listdata2 = peach (Object O in this.listdata2) this .listboxfrm2.items.add (o); FormChild.owner = this; this code is used after the entire FORM2 instantiation; this code is used, so use the Form2_Load event. How can I not use the FORM2_LOAD event? Wait until let's modify the code to implement it.
The following subform code has no change, private void buttonadd_click (object sender, system.eventargs e) {if (this.TextBoxAdd.Text.trim (). Length> 0) {this.listdata2.add (this.textboxAdd.Text .Trim ()); this.listboxfrm2.tems.add (this.TextBoxAdd.Text.trim ());} else messagebox.show ("Please enter the added content!");} Private void buttonDel_click (Object Sender, System . Eventargs e) {int index = this.listboxfrm2.selectedIndIndex; if (index! = - 1) {this.listdata2.removeat (index); this.listboxfrm2.items.removeat (index);} else messagebox.show (" Please select Delete! "); value. 2. Using Custom Attributes or Method Let's talk about how to use custom properties or methods to complete data modification features without using the form2_load event.
Click the Edit button handler main form as follows: private void buttonEdit_Click (object sender, System.EventArgs e) {Form2 formChild = new Form2 (); formChild.ListData2 = this.listData1; formChild.ShowDialog (); this.listBoxFrm1. DataSource = null; this.listboxfrm1.datasource = this.listdata1;} and we remove the list of the main form of listData1 properties, // public arraylist listdata1 // {// get {return this.listdata1;} //} Add ListData2 attribute, public arraylist listdata2 {set {this.listdata2 = value; foreach (object o in this.listdata2) this.listboxfrm2.Items.Add (O);}} can also change the properties to methods, Public void setListData (arraylist listdata) {this.listdata2 = listdata; foreach (objectbo in this.listdata2) this.listboxfrm2.Items.add (o);} and modify the button processing function in the main form : Formchild.listdata2 = this.listdata1; change to formchild.setListData (this.listdata1); summary The function of the function parameters of the form is similar to the implementation of the implementation; in addition, attributes and methods are used to complete the interaction of the data, I think this implementation is very practical, especially in Data is transferred without instances or if there is already an instance. three. This is also a data interaction method we often use using a static class.
Here is a class defined:
Using system;
Using system.collections;
Namespace ZZ
{
Public class appdata
{
Private static arraylist listdata;
Static appdata ()
{
Listdata = new arraylist ();
Listdata.add ("dotnet");
Listdata.add ("c #");
ListData.Add ("ASP.NET");
ListData.Add ("WebService");
Listdata.add ("xml");
}
Public Static ArrayList ListData
{
Get {return listdata;}
}
Public static arraylist getListData ()
{
Return ListData;
}
}
}
The above includes a static class member, ListData, a static constructor static appdata () to initialize ListData's data. There is also a static property ListData and a static getListData () method, and they achieve the same feature is to return ListData. Since the two articles have already spent a lot, this is not detailed, the following is a complete code:
Form1.cs file
Using system;
Using system.drawing;
Using system.collections;
Using system.componentmodel;
Using system.windows.forms;
Namespace ZZ
{
Public Class Form1: System.Windows.Forms.form
{
Private system.windows.Forms.Button ButtonEdit;
Private system.windows.forms.listbox listboxfrm1;
Private system.componentmodel.Container Components = NULL;
Public Form1 ()
{
InitializationComponent ();
This.listboxfrm1.datasource = appdataas.listdata;
}
Protected Override Void Dispose (Bool Disposing)
{
IF (Disposing)
IF (Components! = NULL)
Components.dispose ();
Base.dispose (Disposing);
}
[Stathread]
Static void main ()
{
Application.run (New Form1 ());
}
Private vidinitiRizeComponent ()
{
This.Buttonedit = new system.windows.Forms.Button ();
This.listboxfrm1 = new system.windows.forms.listbox ();
THIS.SUSPENDLAYOUT ();
This.buttonEdit.Location = new system.drawing.point (128, 108);
This.Buttonedit.name = "buttonedit";
This.Buttonedit.tabindex = 1;
This.ButtonEdit.text = "Modify";
This.Buttonedit.Click = new system.eventhandler (this.buttonedit_click);
THISTBOXFRM1.ItemHeight = 12;
this.listboxfrm1.location = new system.drawing.point (12, 8);
THISTBOXFRM1.NAME = "ListBoxFRM1";
This.listboxfrm1.size = new system.drawing.size (108, 124);
this.listboxfrm1.tabindex = 2;
THIS.AUTOSCALEBASESIZE = New System.drawing.size (6, 14);
This.ClientSize = new system.drawing.size (208, 141);
This.Controls.add (this.Listboxfrm1); this.controls.add (this.buttonedit);
THIS.NAME = "Form1";
THIS.TEXT = "Form1";
This.ResumeLayout (false);
}
Private void buttonEDit_click (Object Sender, System.Eventargs E)
{
Form2 formchild = new form2 ();
Formchild.showdialog ();
THISTBOXFRM1.DATASOURCE = NULL;
This.listboxfrm1.datasource = appdataas.listdata;
}
}
}
FORM2.CS file
Using system.drawing;
Using system.collections;
Using system.componentmodel;
Using system.windows.forms;
Namespace ZZ
{
Public Class Form2: System.Windows.Forms.form
{
Private system.windows.Forms.Button Buttonok;
Private system.componentmodel.Container Components = NULL;
Private system.windows.forms.listbox listboxfrm2;
Private system.windows.Forms.Button ButtonAdd;
Private system.windows.Forms.Button Buttondel;
Private system.windows.Forms.TextBox textBoxAdd;
Public Form2 ()
{
InitializationComponent ();
Foreach (Object O IN AppDataS.ListData)
This.ListBoxfrm2.Items.Add (O);
}
Protected Override Void Dispose (Bool Disposing)
{
IF (Disposing)
IF (Components! = NULL)
Components.dispose ();
Base.dispose (Disposing);
}
Private vidinitiRizeComponent ()
{
This.Buttonok = New System.windows.Forms.Button ();
This.listboxfrm2 = new system.windows.forms.listbox ();
This.ButtonAdd = new system.windows.Forms.Button ();
This.Buttondel = new system.windows.Forms.Button ();
This.TextBoxAdd = new system.windows.Forms.TextBox ();
THIS.SUSPENDLAYOUT ();
This.buttonok.location = new system.drawing.point (188, 108);
this.buttonok.name = "buttonok";
this.buttonok.tabindex = 0;
This.Buttonok.Text = "OK";
This.Buttonok.Click = new system.eventhandler (this.buttonok_click; this.listboxfrm2.ItemHeight = 12;
this.listboxfrm2.location = new system.drawing.point (8, 8);
THISTBOXFRM2.NAME = "ListBoxFRM2";
This.listboxfrm2.size = new system.drawing.size (168, 124);
THISTBOXFRM2.TABINDEX = 2;
This.ButtonAdd.Location = new system.drawing.point (188, 44);
This.ButtonAdd.name = "ButtonAdd";
this.buttonadd.tabindex = 3;
This.ButtonAdd.text = "Add";
This.ButtonAdd.click = new system.EventHandler (this.buttonadd_click);
This.buttondel.location = new system.drawing.point (188, 76);
This.buttondel.name = "buttondel";
this.buttondel.tabindex = 4;
This.Buttondel.Text = "Delete";
This.Buttondel.Click = new system.eventhandler (this.buttondel_click);
This.TextBoxAdd.Location = new system.drawing.point (188, 12);
THIS.TEXTBOXADD.NAME = "TextBoxAdd";
This.TextBoxAdd.size = new system.drawing.size (76, 21);
this.TextBoxAdd.tabindex = 5;
THIS.TEXTBOXADD.TEXT = "";
THIS.AUTOSCALEBASESIZE = New System.drawing.size (6, 14);
THIS.CLIENTSIZE = New System.drawing.size (272, 141);
This.Controls.Add (this.TextBoxAdd);
This.Controls.add (this.buttondel);
This.Controls.add (this.buttonadd);
This.Controls.add (this.Listboxfrm2);
This.Controls.add (this.buttonok);
THIS.NAME = "Form2";
THIS.TEXT = "Form2";
This.ResumeLayout (false);
}
Private void Buttonok_Click (Object Sender, System.Eventargs E) {this.close ();}
Private void ButtonAdd_click (Object Sender, System.EventArgs E)
{
IF (THIS.TEXTBOXADD.TEXT.TRIM (). Length> 0)
{
AppDataS.ListData.Add (this.TextBoxAdd.Text.trim ());
This.ListBoxfrm2.Items.add (this.TextBoxAdd.Text.trim ());
}
Else
MessageBox.show ("Please enter the added content!");
}
Private void buttonDel_click (Object Sender, System.EventArgs E)
{
INDEX = this.listboxfrm2.selectedIndIndex;
IF (INDEX! = - 1)
{
AppDataS.ListData.Removeat (INDEX);
This.ListBoxfrm2.Items.Removeat (Index);
}
Else
MessageBox.show ("Please select Delete item!");
}
}
}
Summary, I think the use of static classes is to load the application's configuration file into a static class, so that all forms and other instances can use these data, such as three-layer structure or Multi-layer structures can be accessed instead of passing through multiple instances. Here we discuss the Windows Form, in fact, interact data between two different instances, can be implemented in three articles, unless this unique attribute or method. It's all finished, although not a deep thing, I hope to help some beginners, and you will welcome friends to conduct technical exchanges and improve.