• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

[VB.NET]Để control tự chỉnh lại kích cỡ theo form

Các bài viết hướng dẫn về Visual Basic .NET và C#

Moderators: tungcan5diop, QUANITGROBEST

lsqk
Posts: 7
Joined: Tue 19/11/2013 9:13 am
Has thanked: 30 times

[VB.NET]Để control tự chỉnh lại kích cỡ theo form

Postby lsqk » Thu 18/06/2015 1:05 pm

Tên bài viết: Để control tự chỉnh lại kích cỡ theo form
Cấp độ bài viết: căn bản
Tác giả: lsqk (học từ sách "Kỹ thuật lập trình Visual Basic 5" của Ngọc Anh Thư Press)



Mình có xem qua box này và box "Thủ thuật, mẹo vặt", nhưng không thấy có topic nào hướng dẫn vấn đề này cả, mình mạn phép post bài này vậy. Theo mình thấy, việc lập trình để control tự chỉnh kích cỡ khi kích cỡ của form thay đổi là rất cần thiết. Nếu không biết làm điều này, bạn có thể tắt nút Maximize của form, nhưng chương trình như vậy sẽ bất tiện và kém chuyên nghiệp hơn hẳn.


Đầu tiên, bạn phải hiểu rằng để control tự chỉnh kích cỡ khi kích cỡ form thay đổi, thì chúng ta cần phải giữ vững tỉ lệ giữa các thuộc tính left và width của control với thuộc tính width của form và giữa thuộc tính top và height của control với thuộc tính height của form. Có như thế thì vị trí và kích cỡ của các control mới hợp lý được. Vậy ta cần gán tỉ lệ này vào một biến và bảo đảm biến đó không thay đổi. Biến được nạp giá trị vào lúc form load và giữ nguyên giá trị tới khi form unload. Biến này là biến cấp module. Bạn cũng có thể tạo mỗi control 4 biến phụ thuộc, nhưng như vậy… khổ lắm! :(( Vì vậy, chúng ta sẽ dùng mảng cho nó gọn.

Bắt tay vào làm việc, đầu tiên, ở namespace bạn hãy tạo một structure như sau:
  1. Public Structure ControlProportions
  2.     Public TopProp As Single
  3.     Public LeftProp As Single
  4.     Public HeightProp As Single
  5.     Public WidthProp As Single
  6. End Structure

Nếu chương trình của bạn chỉ có một form thôi thì bạn có thể để structure là Private cũng được. Nhưng nếu có nhiều form thì nên để là Public để dùng chung.

Tiếp đó, trong class của form, bạn nhập vào như sau:
[vbnet] Dim ArrayProportions() As ControlProportions
Private Sub ArrayInitialize()
Dim I As Integer
For I = 0 To Controls.Count - 1
With ArrayProportions(I)
.LeftProp = Controls(I).Left / Me.Size.Width
.TopProp = Controls(I).Top / Me.Size.Height
.WidthProp = Controls(I).Width / Me.Size.Width
.HeightProp = Controls(I).Height / Me.Size.Height
End With
Next
End Sub[/vbnet]
Rồi bạn chọn sự kiện form_load, nhập vào như sau:
[vbnet] Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ReDim ArrayProportions(0 To Controls.Count - 1)
ArrayInitialize()
End Sub[/vbnet]
Có ai thắc mắc vì sao phải là count – 1 mà không phải là count không? ;;)

Vì mảng bắt đầu từ 0! =))

Tiếp đó, bạn chọn sự kiện form_resize, nhập vào như sau:
[vbnet] Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
Dim I As Integer
For I = 0 To Controls.Count - 1
Controls(I).Left = ArrayProportions(I).LeftProp * Me.Size.Width
Controls(I).Top = ArrayProportions(I).TopProp * Me.Size.Height
Controls(I).Width = ArrayProportions(I).WidthProp * Me.Size.Width
Controls(I).Height = ArrayProportions(I).HeightProp * Me.Size.Height
Next
End Sub[/vbnet]


Trên đây là hướng dẫn lập trình tự chỉnh kích cỡ control với những form không dùng container. Nếu dùng container thì mã sẽ dài dòng hơn:

Bạn vẫn khai báo structure như cũ, bắt đầu từ mảng trở đi phải thay đổi. Cụ thể, trong class của form bạn khai báo mảng như sau:
[vbnet]Dim ArrPro(,) As ControlProportions[/vbnet]
Sub ArrayInitialize như sau:
[vbnet] Private Sub ArrayInitialize()
Dim i As Short = 0, n As Short = 0
For i = 0 To Controls.Count - 1
With ArrPro(i, 0)
.LeftProp = Controls(i).Left / Me.Size.Width
.TopProp = Controls(i).Top / Me.Size.Height
.WidthProp = Controls(i).Width / Me.Size.Width
.HeightProp = Controls(i).Height / Me.Size.Height
End With
If Controls(i).Controls.Count > 0 Then
For n = 1 To Controls(i).Controls.Count
With ArrPro(i, n)
.LeftProp = Controls(i).Controls(n - 1).Left / Controls(i).Width
.TopProp = Controls(i).Controls(n - 1).Top / Controls(i).Height
.WidthProp = Controls(i).Controls(n - 1).Width / Controls(i).Width
.HeightProp = Controls(i).Controls(n - 1).Height / Controls(i).Height
End With
Next
End If
Next
End Sub[/vbnet]
Có ai thắc mắc là tại sao phải dùng n - 1 mà không dùng n không? ;;) Vì tập hợp controls bắt đầu từ 0, mà ở đây n bắt đầu từ 1, nên ta phải trừ đi 1! :))

Hai sự kiện form_load và form_resize như sau:
[vbnet] Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim i As Short = 0, n As Short = 0, k As Short = Controls.Count
For i = 0 To Controls.Count - 1
If Controls(i).Controls.Count > k Then
k = Controls(i).Controls.Count
End If
Next
ReDim ArrPro(Controls.Count - 1, k)
ArrayInitialize()
End Sub[/vbnet]
[vbnet] Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
Dim i As Short = 0, n As Short = 0
If Controls.Count > 0 Then
For i = 0 To Controls.Count - 1
Controls(i).Left = ArrPro(i, 0).LeftProp * Me.Size.Width
Controls(i).Top = ArrPro(i, 0).TopProp * Me.Size.Height
Controls(i).Width = ArrPro(i, 0).WidthProp * Me.Size.Width
Controls(i).Height = ArrPro(i, 0).HeightProp * Me.Size.Height
If Controls(i).Controls.Count > 0 Then
For n = 1 To Controls(i).Controls.Count
Controls(i).Controls(n - 1).Left = ArrPro(i, n).LeftProp * Controls(i).Width
Controls(i).Controls(n - 1).Top = ArrPro(i, n).TopProp * Controls(i).Height
Controls(i).Controls(n - 1).Width = ArrPro(i, n).WidthProp * Controls(i).Width
Controls(i).Controls(n - 1).Height = ArrPro(i, n).HeightProp * Controls(i).Height
Next
End If
Next
End If
End Sub[/vbnet]
Có ai thắc mắc vì sao phải có điều kiện If Controls.Count > 0 ở đây không? ;;) Vì khi chương trình mới bắt đầu chạy, trên form còn chưa có control nào, sự kiện resize đã xảy ra. Nếu bạn không kiểm tra điều kiện này, chương trình sẽ báo lỗi. :))


Nếu bạn sử dụng nhiều container lồng nhau thì bạn thêm chiều cho mảng, khai báo thêm biến kiểu short và thêm vòng lặp tương tự như trên.

Có ai thắc mắc container là cái gì không? ;;) Container là control dùng để chứa control khác. Tab control, panel, group box là những ví dụ về container. Trong toolbox có hẳn một phần dành riêng cho container, chỉ cần bạn chú ý là thấy. =))



User avatar
khoaakt
Thành viên năng nổ
Thành viên năng nổ
Posts: 75
Joined: Tue 19/06/2012 6:30 pm
Location: http://việtnam.vn/Kontum/Trường/THPT Chuyên Nguyễn Tất Thành.htm
Has thanked: 8 times
Been thanked: 7 times
Contact:

Re: [VB.NET]Để control tự chỉnh lại kích cỡ theo form

Postby khoaakt » Wed 24/06/2015 11:39 am

Thuộc tính Anchor nhanh gấp 10 lần nhé =))

User avatar
lipton150786
Thành viên tâm huyết
Thành viên tâm huyết
Posts: 345
Joined: Thu 18/11/2010 10:00 pm
Has thanked: 5 times
Been thanked: 29 times

Re: [VB.NET]Để control tự chỉnh lại kích cỡ theo form

Postby lipton150786 » Wed 26/08/2015 10:32 am

nếu dùng Anchor thì sẽ thay cho đoạn code nào ở trên , xin chỉ rỏ hơn được không

lsqk
Posts: 7
Joined: Tue 19/11/2013 9:13 am
Has thanked: 30 times

Re: [VB.NET]Để control tự chỉnh lại kích cỡ theo form

Postby lsqk » Fri 25/11/2016 4:45 pm

Xin lỗi bạn lipton150786 vì chậm trả lời, tại lâu quá không vào diễn đàn!

Nếu bạn muốn dùng thuộc tính Anchor của control thì không cần nhập đoạn mã của mình post. Bạn chỉ cần điều chỉnh thuộc tính của từng control trong phần Properties cho chúng thay đổi theo đúng ý bạn khi kích thước form thay đổi.

Thật ra hai cách này là khác nhau. Thuộc tính anchor lưu giữ khoảng cách từ biên đối tượng tới biên tương ứng của form, còn đoạn mã của mình tính lại kích thước control theo kích thước của form để giữ nguyên tỷ lệ. Tùy theo trường hợp mà hai cách có thể có kết quả giống hoặc khác nhau.

Mình thì lười nên viết sẵn mấy đoạn mã này, khi nào lập trình thì copy rồi paste vào thôi. Dù viết phần mềm có mấy chục form cũng không tốn thời gian mấy. :-"


Return to “[.NET] Bài viết hướng dẫn”

Who is online

Users browsing this forum: No registered users and 3 guests