Lessons IX : Những chức năng mới trong giao diện cửa sổ của VB.NET (phần II)

Logo of Vovisoft

Bài 9 ZZZZZZZZ

Những chức năng mới trong giao diện cửa sổ của VB.NET (phần II)

Sự khác biệt trong các Hộp Giao Thoại (Dialog Boxes)

Trong VB6, các hộp giao thoại thật ra là những form bình thường nhưng được hiển thị với parameter vbModal, tức là trong Modal mode. Điều nầy khíến cho hộp giao thoại trở nên form tích cực (active form) duy nhất trong chương trình cho đến khi nó đi khuất.

Một hộp giao thoại cần một phương tiện để liên lạc với form gọi nó (calling form). Trong VB6, ta giải quyết vấn đề nầy bằng cách chế ra một property tạm gọi là Action. Ta dùng Read-only property Action như sau trong một hộp giao thoại có hai buttons, OKCancel:

' VB6 code used for Dialog Boxes
Public Enum dialogAction 
   actionOK = 1 
   actionCancel = 2 
End Enum 

Dim mAction As dialogAction 

Public Property Get Action() As dialogAction 
   Action = mAction 
End Property 

Private Sub cmdOK_Click() 
   ' Get here when user click the OK button
   mAction = actionOK 
   ' Hide the Dialog Box to return control to calling form
   Me.Hide 
End Sub 

Private Sub cmdCancel_Click() 
   ' Get here when user click the Cancel button
   mAction = actionCancel 
   ' Hide the Dialog Box to return control to calling form
   Me.Hide 
End Sub

Chú ý ta dùng Enumerated type dialogAction. Nó có hai trị số: actionOKactionCancel. Property Action thuộc loại enumerated type nầy. Khi user click một button, ta set trị số cho local variable mAction rồi Hide cái dialog box. Cái Giao thoại phải được dấu đi (hidden) nhưng không unloaded, vì cái calling form còn phải truy cập dialog box để đọc trị số của property Action để biết user vừa mới click button nào.

Giả dụ ta đặt tên cho hộp giao thoại đó là frmDialog. Để gọi một hộp giao thoại từ một form khác trong VB6 ta có thể code như sau:

Dim Dialog As frmDialog 
Set Dialog = New frmDialog  ' Instantiate a Dialog Box
' Show dialog box in Modal mode
Dialog.Show vbModal

Nhưng bao nhiêu đó chỉ là hiển thị hộp giao thoại thôi. Sau khi hộp giao thoại đã Hide rồi ta còn phải truy cập nó để đọc trị số của property Action. Do đó ta cần phải viết thêm codes cho đầy đủ sau đây:

Dim Dialog As frmDialog 
Set Dialog = New frmDialog  ' Instantiate a Dialog Box
' Show dialog box in Modal mode
Dialog.Show vbModal 
' Get here after the dialog box has hidden, but still loaded
' Now process the Action
Select Case Dialog.Action 
Case actionOK 
   ' code goes here for normal processing
Case actionCancel 
   ' code goes here for user canceling
End Select 
Unload Dialog  ' Now we can unload the dialog box

Có hai sự thay đổi quan trọng trong VB.NET, đó là dùng ShowDialogDialogResult.

ShowDialog thay vì Show vbModal

Argument vbModal không được hỗ trợ trong VB.NET. Thay vào đó, một form có thể dùng method ShowDialog. Dưới đây là sự so sánh của coding trong VB6 và VB.NET.

VB6 code:

Dim Dialog As frmDialog 
Set Dialog = New frmDialog  ' Instantiate a Dialog Box
' Show dialog box in Modal mode
Dialog.Show vbModal

VB.NET code:

Dim Dialog As New frmDialog() 
' Show dialog box in Modal mode
Dialog.ShowDialog

Để ý là trong VB.NET ở hàng code đầu ta có thể kết hợp hai chuyện khai báo và instantiate form mới trong một statement. Hàng code cuối cho thấy sự thay đổi từ Show vbModal qua ShowDialog.

DialogResult

Trong VB.NET, khi một form khải thị bằng method ShowDialog, nó đã dự bị sẵn một property tên là DialogResult để calling form có thể truy cập.

DialogResult có thể mang một trong những trị số enumerated sau đây:

  • DialogResult.Abort
  • DialogResult.Cancel
  • DialogResult.Ignore
  • DialogResult.No
  • DialogResult.None
  • DialogResult.OK
  • DialogResult.Retry
  • DialogResult.Yes

Có điểm rất tiện là khi DialogResult được set cho một trị số thì dialog được dấu đi (hidden) một cách tự động.

Cách đơn giản nhất để set trị số cho DialogResult là assign một trị số cho property DialogResult của một button. Khi user click button ấy thì DialogResult của hộp giao thoại lấy trị số của property DialogResult của button và hộp giao thoại Hide.

Để biểu diễn ShowDialog trong VB.NET, kèm theo đây là mã nguồn của một thí dụ. Trong thí dụ nầy ta tạo một form tên frmDialog có hai button tên OK và Cancel. Ta set property DialogResult của button OK thành OK và property DialogResult của button Cancel thành Cancel. Form frmDialog hoàn toàn không có một hàng code nào cả.

Form chính của chương trình, Form1, chỉ có một button tên BtnShowDialog với code cho Event Click như dưới đây:

Private Sub BtnShowDialog_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnShowDialog.Click 
  ' Declare and instantiate a Dialog Box
   Dim Dialog As New frmDialog() 
  ' Show the Dialog Box in Modal mode
   Dialog.ShowDialog() 
  ' get here after user has clicked a button and the Dialog box has hidden
  ' Process the DialogResult
   Select Case Dialog.DialogResult 
   Case DialogResult.OK 
      MsgBox("User clicked OK, se please go ahead") 
   Case DialogResult.Cancel 
      MsgBox("Sorry, but User clicked Cancel") 
   End Select 
   Dialog = Nothing ' Dispose the Dialog Box
End Sub

Bạn có thể chạy chương trình rồi click button ShowDialog. Khi Dialog box hiển thị, thử click một trong hai buttons trên ấy.

So sánh với VB6, ta thấy dùng Dialog Box trong VB.NET đơn giản và tự nhiên hơn.

Nếu không dùng Property DialogResult của một button trong Dialog Box để trả về kết quả DialogResult, ta cũng có thể dùng code trong Dialog form như sau:

  Me.DialogResult = DialogResult.Retry

Hàng code trên set DialogResult của Dialog form thành DialogResult.Retry và kềm theo phản ứng phụ là Hide Dialog Box. Calling form sẽ truy cập được kết quả DialogResult.Retry nầy.

Sự khác biệt về sắp đặt vị trí cho Forms và Controls

VB.NET có những chức năng về positioning và layout tương tợ như trong VB6, nhưng cách thực thi hơi khác.

Property Location

Thay vào các properties LeftTop trong VB6, forms và controls trong VB.NET có property Location. Property Location nhận và trả về một structure tên Point, có tọa độ XY tương ứng với Left và Top mà ta dùng trước đây.

Structure point được dùng trong nhiều áp dụng về đồ họa trong GDI+ (Graphic Devices Interface plus) của .NET.

Thật ra, trong code ta vẫn còn dùng Top và Left được như xưa. Nhưng Top và Left không hiện ra trong cửa sổ Properties của forms hay controls. Để chỉ định một vị trí mới cho form, ta có thể code như sau:

    Me.Location = (New Point(200, 100))

Property Size

Property Size trong VB.NET có cùng một ý niệm như property Location, có điều nó tương xứng với Width và Height. Property Size nhận và trả về một structure tên Size, có chiều cao và chiều rộng để áp dụng cùng một lúc thay vì tuần tự từng chiều. Giống như Left và Top, trong code ta vẫn còn dùng Width và Height được như xưa. Nhưng Width và Height không hiện ra trong cửa sổ Properties của forms hay controls. Để thay đổi Size của một form, ta có thể code như sau:

    Me.Size = (New Size(300, 400))

ReSize nhiều controls

VS.NET cho ta một chức năng mới là Resize nhiều controls cùng một lúc. Trước hết bạn Select nhiều controls bằng cách drag một dây thun (rubber band) bao quanh chúng hay ấn nút Ctrl trong lúc click các controls. Kế đó, tập trung việc resize vào một control, các controls kia cũng được resized theo.

Các features thiết kế chung cho các Controls

Tab Order của các Controls

Sắp đặt thứ tự trong Tab của các controls (Tab Order) trên một form đôi khi rất phiền phức trong VB6. VS.NET cho ta một feature rất tiện dụng để làm việc nầy. Để khởi động feature ấy, ta dùng IDE menu command View | Tab Order. Nó sẽ hiển thị một con số nhỏ ở góc trên trái của mỗi control, cho thấy trị số Tab Index của mỗi control. Bây giờ ta chỉ cần click lên từng control một theo thứ tự mà ta muốn.

Dưới đây là screenshot của một form sau khi user chỉ định Tab Order cho các controls. Muốn ra khỏi Tab Order mode, ta bấm menu command View | Tab Order một lần nữa.

Ghi chú:Trong VB.NET nhiều controls có thể có cùng một Tab Index. Trong trường hợp ấy, thứ tự về Tab của chúng được quyết định dựa vào z-order. Control có z-order cao nhất sẽ nhận focus trước nhất trong nhóm. Z-order của một control có thể được thay đổi bằng cách right click control rồi chọn Bring to Front.

Control Arrays

Khi nghe nói VB.NET không hỗ trợ Control Arrays chắc bạn buồn năm phút. Có hai lý do tại sao bạn cần Control Arrays:

  • Dùng cùng một Event handler (thí dụ như Sub BtnBrowse_Click) để xử lý Event từ nhiều Controls tương tự.
  • Để dynamically tạo thêm Controls trong form lúc đang chạy program (at runtime).

May thay, VB.NET cung cấp cho ta một phương tiện khác để khỏi phải thua thiệt. VB.NET cho phép ta linh động bổ nhiệm các methods để xử lý Events của các controls. Điểm thứ nhất bạn sẽ chú ý là bạn không thể dùng cùng một tên cho nhiều controls nữa. Property Index đã bị khai tử.

Trong VB.NET bạn có thể dùng một Event handler duy nhất để xử lý Events đến từ các controls tương tự. Trước đây ta dựa vào Index để biết Event phát xuất từ control nào. Bây giờ bạn dựa vào parameter Sender.

Để minh họa điểm nầy, ta sẽ viết một chương trình có hai buttons, Button1 và Button2, nằm trên form chính. Double click Button1 để viết code xử lý Event Button1.Click. Muốn dùng cùng một Event Sub nầy để xử lý luôn Event Click đến từ Button2, bạn chỉ cần thêm chữ Button2.Click vào cuối cái Handles List của Sub Button1_Click. Để cho có vẻ tổng quát ta rename Sub Button1_Click thành Sub Button_Click.

Bây giờ ta viết vài dòng code đơn giản để hiển thị cho biết Event Click đến từ Button nào:

' Note that we change the name of the Sub from Button1_Click to Button_Click to
' make it more general, since we're going to use this same Sub to handle Click
' Events originated from many different Buttons
' Also note that we add the word Button2.Click to the end of Sub Button_Click declaration
Private Sub Button_Click( ByVal sender As System.Object, ByVal e As System.EventArgs)  _
                      Handles Button1.Click, Button2.Click 
   Dim btnClicked As Button 
  ' Type cast sender to Button
   btnClicked =  CType(sender, Button) 
  ' Show what button was clicked
   MessageBox.Show("You clicked """ & btnClicked.Text & """") 
End Sub

Thử chạy chương trình và click Button2, bạn sẽ thấy hình dưới đây:

Để biểu diễn chức năng quản lý Event Handling at runtime, ta sẽ đặt một button tên BtnAddNewButton vào form để nó dynamically add một button thứ ba tên Button3. Ta muốn button nầy cũng sẽ dùng Sub Button_Click để xử lý Event Click của nó. Vì không thể đánh thêm chữ Button3.Click vào cuối câu Sub Button_Click như trước đây ta đã làm với Button2.Click, nên at runtime ta sẽ dùng statement:

' Tell system to use Button_Click as Event Handler for the Event Button3.Click
AddHandler newButton.Click, AddressOf Me.Button_Click

Mã nguồn đầy đủ của Sub BtnAddNewButton_Click được liệt kê dưới đây:

Private Sub BtnAddNewButton_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnAddNewButton.Click 
  ' Declare and instantiate a Button
   Dim newButton As New Button() 
  ' Set it up on the form
   With newButton 
      .Text = "Button3" ' Text of this new button
      .Location = New Point(230, 120) ' define its location on the form
      .Size = New Size(88, 40) ' define its size
   End With 
  ' Add the new button to the form's collection of controls
   Me.Controls.Add(newButton) 
  ' Tell system to use Button_Click as Event Handler for the Event Button3.Click
   AddHandler newButton.Click, AddressOf Me.Button_Click 
End Sub

Khi user click BtnAddNewButton, Button3 với Size(88,40) sẽ được tạo ra và đặt ở Location(230,120) trên form. Kế nó chương trình thực hiện hai chuyện quan trọng: Add button mới nầy vào collection of controls của form và đăng ký (register) việc dùng Sub Button_Click làm Event Handler của Event Click của nó.

Làm xong mấy chuyện nầy rồi, bạn chạy chương trình, click AddNewButton để thêm Button3 vào form, kế đó click Button3, bạn sẽ thấy hình dưới đây:

Bạn có thể tải về chương trình ControlArrays nầy tại đây.

  Học Microsoft .NET

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: