VCL.NET and Windows.Forms


Controls located in the Windows.Forms namespace are to .NET languages the same thing VCL is to Delphi and C++Builder languages — a collection of controls that allow us to build GUI applications.

Building Windows.Forms and VCL.NET applications inside the IDE is pretty much the same. Figure 29-15 and the following points illustrate this:

image from book
Figure 29-15: Building Windows.Forms applications in Delphi

  • The center of a VCL.NET application is the TForm class (located in the Borland.VCL.Forms unit), and the center of a Windows.Forms application (either Delphi for .NET or C#) is the Form class, located in the System.Windows.Forms namespace, and physically in the System.Windows.Forms assembly.

  • Both VCL.NET and Windows.Forms applications are built by dropping components on the Designer Surface (form).

  • To build either VCL.NET or Windows.Forms applications, you have to write code in response to various events fired by the components.

  • Both frameworks are built on top of the Win32 API.

There are also differences between the two frameworks:

  • The VCL framework can be used to build applications that run on Windows and Linux (if you install CrossKylix you can build both Windows and Kylix applications on Windows), while Windows.Forms applications only run on the .NET platform.

  • With minor changes, VCL applications can be converted to VCL.NET and target the .NET platform. Windows.Forms applications cannot target any platform besides .NET.

  • VCL applications can currently be built only by Delphi and C++Builder developers, and VCL.NET applications can only be built by Delphi developers. Windows.Forms applications can be created with any .NET language.

  • Custom VCL/VCL.NET components can only be created by Delphi and C++Builder developers (Win32 version). .NET components can be created in any .NET language.

  • VCL objects are stored in separate files (*.dfm files in VCL, *.nfm files in VCL.NET). Windows.Forms controls are stored in the main source file as a series of statements that create them and initialize their properties. (Listing 29-23 shows the source code of the main form from a Delphi for .NET Windows.Forms application.)

  • Windows.Forms does not have anything similar to actions and the TActionList/TActionManager components; however, VCL doesn't have an ErrorProvider component. :)

  • Windows.Forms applications are easier to deploy because the System.Windows.Forms assembly ships with the .NET framework. VCL.NET applications can be "standalone" (require only the .NET framework) but take up approximately 2 MB, or they can reference VCL assemblies and be much smaller (in this case, you'll have to deploy Borland.Delphi.dll, Borland.Vcl.dll, and Borland.VclRtl.dll assemblies alongside your application).

Listing 29-23: The source code of a basic Windows.Forms form with a single Label component

image from book
unit MainForm; interface uses   System.Drawing, System.Collections, System.ComponentModel,   System.Windows.Forms, System.Data; type   TMainForm = class(System.Windows.Forms.Form)   { $REGION 'Designer Managed Code' }   strict private     /// <summary>     /// Required designer variable.     /// </summary>     Components: System.ComponentModel.Container;     Label1: System.Windows.Forms.Label;     /// <summary>     /// Required method for Designer support - do not modify     /// the contents of this method with the code editor.     /// </summary>     procedure InitializeComponent;   { $ENDREGION }   strict protected     /// <summary>     /// Clean up any resources being used.     /// </summary>     procedure Dispose(Disposing: Boolean); override;   private     { Private Declarations }   public     constructor Create;   end;    [assembly: RuntimeRequiredAttribute(TypeOf(TMainForm))] implementation { $AUTOBOX ON } { $REGION 'Windows Form Designer generated code' } /// <summary> /// Required method for Designer support -- do not modify /// the contents of this method with the code editor. /// </summary> procedure TMainForm.InitializeComponent; begin   Self.Label1 := System.Windows.Forms.Label.Create;   Self.SuspendLayout;   //   // Label1   //   Self.Label1.Location := System.Drawing.Point.Create(32, 32);   Self.Label1.Name := 'Label1';   Self.Label1.TabIndex := 0;   Self.Label1.Text := 'Label1';   //   // TMainForm   //   Self.AutoScaleBaseSize := System.Drawing.Size.Create(5, 13);   Self.ClientSize := System.Drawing.Size.Create(448, 270);   Self.Controls.Add(Self.Label1);   Self.Name := 'TMainForm';   Self.Text := 'Delphi for .NET Windows.Forms Application';   Self.ResumeLayout(False); end; { $ENDREGION } procedure TMainForm.Dispose(Disposing: Boolean); begin   if Disposing then   begin     if Components <> nil then       Components.Dispose();   end;   inherited Dispose(Disposing); end; constructor TMainForm.Create; begin   inherited Create;   //   // Required for Windows Form Designer support   //   InitializeComponent;   //   // TODO: Add any constructor code after InitializeComponent call   // end; end.
image from book

Windows.Forms Application's Entry Point

As in .NET console applications, the entry point of a Windows.Forms application is the Main method. With Windows.Forms applications, the Main method contains a single line of code that creates the main form and calls the Run method of the global .NET Application object (instance of System.Windows.Forms.Application) to start the application and display the main form on screen. Listings 29-24A and 29-24B show the Main methods from a Delphi for .NET Windows.Forms application and a C# Windows.Forms application.

Listing 29-24A: The entry point of a Delphi for .NET Windows.Forms application

image from book
[STAThread] begin   Application.Run(TWinForm.Create); end.
image from book

Listing 29-24B: The entry point of a C# Windows.Forms application

image from book
[STAThread] static void Main() {    Application.Run(new WinForm()); }
image from book

Multicast Events

Among other differences, Windows.Forms and VCL frameworks differ in the fact that Windows.Forms controls can call multiple handlers in response to an event, while VCL components traditionally only fire a single event handler in response to an event.

In VCL applications, you can assign event handlers to an event using the assignment operator. If you assign the nil value to an event handler, you are removing the event handler from the event.

In Windows.Forms applications, you can add and remove multiple event handlers from an event using the Include and Exclude procedures. To see how this is done, take a look at Figure 29-16 and the example in Listing 29-25.

image from book
Figure 29-16: Windows.Forms application that illustrates multicast events

The Button1 and Button2 components in this example have their own event handlers that use the Show method of the MessageBox class to display a message dialog box. Button3 doesn't have its own Click event handler but calls the Click event handlers of Button1 and Button2.

The two event handlers are added to the Click event using the Include procedure in the form's OnLoad event (equivalent to the OnCreate event in VCL applications).

Listing 29-25: Assigning multiple event handlers to an event in a Delphi for .NET Windows.Forms application

image from book
procedure TWinForm.TWinForm_Load(sender: System.Object; e: System.EventArgs); begin   // add event handlers of Button1 and Button2 to the   // Click event of Button3   Include(Button3.Click, Button1_Click);   Include(Button3.Click, Button2_Click); end; procedure TWinForm.Button2_Click(sender: System.Object; e: System.EventArgs); begin   MessageBox.Show('Button2.Click', 'Message',     MessageBoxButtons.OK, MessageBoxIcon.Information); end; procedure TWinForm.Button1_Click(sender: System.Object; e: System.EventArgs); begin   MessageBox.Show('Button1.Click', 'Message',     MessageBoxButtons.OK, MessageBoxIcon.Information); end;
image from book

In C#, you use the += to add event handlers to an event and –= to remove an event handler from an event (see Listing 29-26). Besides using these two operators, you have to instantiate the System.EventHandler delegate (dele- gates are covered in the next chapter) and pass to the EventHandler's constructor the name of the event handler you wish to add to the event.

Listing 29-26: Assigning multiple event handlers to an event in a C# Windows.Forms application

image from book
private void button1_Click(object sender, System.EventArgs e) {    MessageBox.Show("button1.Click", "Message",       MessageBoxButtons.OK, MessageBoxIcon.Information); } private void button2_Click(object sender, System.EventArgs e) {    MessageBox.Show("button2.Click", "Message",       MessageBoxButtons.OK, MessageBoxIcon.Information); } private void WinForm_Load(object sender, System.EventArgs e) {    button3.Click += new System.EventHandler(button1_Click);    button3.Click += new System.EventHandler(button2_Click); }
image from book

Creating Windows.Forms Controls Dynamically

When creating controls dynamically, you have to manually set the control's parent, because the control is displayed on its parent control. In VCL, you display a control by setting a container control, like the main form, to its Parent property. In Windows.Forms applications, you add the component to the container control by calling the Add method of the container control's Controls collection.

Listing 29-27 shows how to dynamically create a Windows.Forms.Button control and how to display it on the main form. Figure 29-17 shows the result of the code in Listing 29-27.

image from book
Figure 29-17: A dynamically created Windows.Forms.Button calling a dynamically assigned event handler

Listing 29-27: Dynamically creating a Windows.Forms.Button control

image from book
procedure TWinForm.DynamicEvent(sender: System.Object; e: System.EventArgs); begin   System.Windows.Forms.MessageBox.Show('The form will now close.',     'Message', MessageBoxButtons.OK, MessageBoxIcon.Information);   Self.Close; end; procedure TWinForm.TWinForm_Load(sender: System.Object; e: System.EventArgs); var   btn: Button; begin   btn := Button.Create;   btn.Location := System.Drawing.Point.Create(10, 10); // top and left   btn.Size := System.Drawing.Size.Create(100, 25);        // width and height   btn.Text := 'Close';   Include(btn.Click, DynamicEvent);   // equivalent to "Button.Parent := Self" in VCL   Self.Controls.Add(btn); end;
image from book

Windows Forms MDI Essentials

Figure 29-18 shows a very simple Windows.Forms MDI application that we are going to build in this section.

image from book
Figure 29-18: A Windows.Forms MDI application

To have a Windows.Forms form act as an MDI parent, set its IsMDIContainer property to True. Then add a MainMenu and an OpenFileDialog component from the components category to it. To allow users to select multiple files with the OpenFileDialog component, set its MultiSelect property to True.

Now add another Windows Form to the project and drop a TextBox component on it. The Windows.Forms.TextBox control can act as the TEdit and TMemo component. To display an entire text file in the TextBox control, set its Multiline property to True and its Dock property to Fill, to have it cover the entire form.

To load an entire text file into the TextBox control, you have to use the System.IO.StreamReader class. Listing 29-28 shows how to load a text file into a TextBox control.

Listing 29-28: Loading an entire text file into a Windows.Forms.TextBox control

image from book
unit Child; interface uses   System.Drawing, System.Collections, System.ComponentModel,   System.Windows.Forms, System.Data, System.IO; type   TChildForm = class(System.Windows.Forms.Form)   public     constructor Create;     procedure LoadFile(FileName: string);   end; implementation procedure TChildForm.LoadFile(FileName: string); var   sr: System.IO.StreamReader; begin   sr := System.IO.StreamReader.Create(FileName);   try     TextBox1.Text := sr.ReadToEnd;   finally     sr.Close;   end; end;
image from book

The last tasks you have to do are create a File menu and the File ® Open item and write code that displays the OpenFileDialog and creates child forms. This code is displayed in Listing 29-29.

Listing 29-29: Creating child forms

image from book
procedure TWinForm.FileOpenItem_Click(sender: System.Object; e: System.EventArgs); var   fileName: string;   childForm: TChildForm; begin   // display the OpenFileDialog   if OpenFileDialog1.ShowDialog =     System.Windows.Forms.DialogResult.OK then   begin     // browse through the selected files     for fileName in OpenFileDialog1.FileNames do     begin       childForm := TChildForm.Create;       // this changes the form to an mdi child form       childForm.MdiParent := Self;       childForm.Text := fileName;       childForm.LoadFile(fileName);       childForm.Show;     end;     // for   end;       // if ShowDialog end;
image from book



Inside Delphi 2006
Inside Delphi 2006 (Wordware Delphi Developers Library)
ISBN: 1598220039
EAN: 2147483647
Year: 2004
Pages: 212
Authors: Ivan Hladni

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net