Layout

Penataan kontrol dengan Anchoring, Docking, dan TableLayoutPanel.

Daftar isi

Antarmuka yang diposisikan dengan angka piksel tetap akan rusak begitu jendela diubah ukurannya, dan topik ini menyediakan tiga alat Windows Forms untuk mencegahnya. Penjangkaran (anchoring) menjaga jarak kontrol ke tepi tertentu, penempelan (docking) membuat kontrol mengisi tepi form, sedangkan TableLayoutPanel membagi form menjadi baris dan kolom yang proporsinya tetap terjaga. Setelah membaca topik ini, form dapat dirancang agar tampil baik pada ukuran jendela mana pun.

Masalah penempatan piksel tetap#

Properti Location dan Size menempatkan kontrol pada koordinat yang tidak berubah, dan inilah sebabnya form kecil yang dibangun cepat menjadi tidak terkendali saat diubah ukurannya. Bayangkan tombol Simpan yang diletakkan di sudut kanan bawah jendela sebesar 300 piksel. Ketika jendela diperlebar ke 800 piksel, tombol itu tetap berada pada koordinat 280 piksel sehingga tampak melayang di tengah, dengan ruang kosong luas di kanannya.

Masalah ini tidak terjadi pada aplikasi sungguhan karena Windows Forms menyediakan perilaku penataan yang dihitung ulang setiap kali jendela berubah. Ketiga alat pada topik ini bekerja pada waktu yang sama, yaitu ketika event Resize form diterbitkan, hanya rumusnya yang berbeda. Pemilihan alat bergantung pada bentuk yang diinginkan, dan ketiganya dapat digunakan berdampingan dalam satu form.

Menjangkar kontrol dengan Anchor#

Properti Anchor menjaga jarak kontrol terhadap tepi form yang dipilihnya. Nilai bawaannya adalah AnchorStyles.Top Or AnchorStyles.Left, yang berarti jarak ke tepi atas dan kiri selalu sama, sehingga kontrol berdiam di tempat ketika jendela diperbesar. Menambahkan tepi lain mengubah perilakunya, misalnya jangkar Top Or Right membuat kontrol mengikuti tepi kanan, dan jangkar empat arah membuat kontrol ikut meregang bersama jendela.

vb Contoh: kombinasi Anchor yang lazim
' tidak-dijalankan
tombolSimpan.Anchor = AnchorStyles.Top Or AnchorStyles.Right
daftarNilai.Anchor = AnchorStyles.Top Or AnchorStyles.Bottom _
    Or AnchorStyles.Left Or AnchorStyles.Right

Cara membaca kombinasi tersebut sederhana. Pada baris pertama, jarak tombol ke tepi kanan form tetap sama meskipun lebarnya bertambah, sehingga tombol senantiasa menempel di sudut kanan. Pada baris kedua, jarak daftar ke keempat tepinya tetap, sehingga satu-satunya cara memenuhi syarat itu adalah meregangkan daftar itu sendiri. Kombinasi inilah yang digunakan pada kontrol utama sebuah form, sedangkan tombol aksi biasanya cukup dijangkarkan ke sudut tempatnya berada.

Menempel kontrol dengan Dock#

Properti Dock menempelkan kontrol ke satu tepi form atau mengisinya seluruhnya. Nilai DockStyle.Top membuat kontrol menempel ke tepi atas dengan lebar penuh, DockStyle.Bottom melakukan hal yang sama ke tepi bawah, sedangkan DockStyle.Fill membuat kontrol mengisi seluruh ruang yang tersisa. Kontrol yang ter-dock tidak lagi mengindahkan Location karena posisinya ditentukan sistem penataan.

vb Contoh: Dock pada bilah atas dan isi utama
' tidak-dijalankan
bilahAtas.Dock = DockStyle.Top
bilahAtas.Height = 48
daftarUtama.Dock = DockStyle.Fill

Kode tersebut membangun pola yang paling sering ditemui pada aplikasi berjendela, yaitu bilah tetap di atas dan konten yang mengisi sisanya. Saat jendela diperlebar, bilah atas ikut melebar penuh tanpa diatur, sedangkan tingginya tetap 48 piksel karena ditetapkan sendiri. Urutan penambahan kontrol juga berpengaruh pada ruang yang tersisa, sebab kontrol yang didaftarkan lebih dahulu mengambil tepinya lebih dahulu.

Menata baris dan kolom dengan TableLayoutPanel#

TableLayoutPanel membagi area menjadi sel berdasarkan jumlah kolom dan baris, lalu setiap kontrol ditempatkan pada sel tertentu dengan Controls.Add(kontrol, kolom, baris). Jumlah selnya ditetapkan lewat ColumnCount dan RowCount, dan indeksnya dimulai dari nol, sehingga kolom pertama bernilai 0. Lebar setiap kolom dan tinggi setiap baris diatur lewat ColumnStyles dan RowStyles dengan tiga pilihan ukuran, yaitu Absolute dalam piksel, AutoSize mengikuti isinya, dan Percent sebagian dari ruang tersisa. Kontrol yang membutuhkan lebih dari satu sel diatur lewat SetColumnSpan atau SetRowSpan.

Di dalam sel, kontrol biasanya diberi Dock = DockStyle.Fill agar mengisi selnya, dan jarak antar kontrol diatur lewat Padding pada tabel atau Margin pada kontrol. Pendekatan ini menggantikan penghitungan koordinat manual, karena perubahan ukuran jendela dibagi otomatis mengikuti persentase yang sudah ditetapkan. Pola yang lazim adalah kolom Percent untuk konten yang boleh tumbuh dan baris AutoSize untuk masukan singkat, sedangkan baris Percent menerima sisa tinggi untuk daftar atau kisi data.

Memilih dan menggabungkan keduanya#

Diagram berikut memperlihatkan perbedaan perilaku Anchor dan Dock pada jendela yang diperbesar. Sisi kiri menunjukkan kontrol yang dijangkarkan ke tepi kanan-bawah dengan jaraknya yang tetap, sedangkan sisi kanan menunjukkan bilah yang ter-dock ke tepi atas beserta isi yang mengisi sisanya.

AnchorDock→ukuran awalsetelah diperbesarjarak ke tepi yang dijangkari tetap sama→ukuran awalsetelah diperbesarmenempel penuh ke tepi dan ikut melebar
Perilaku Anchor dan Dock ketika jendela diubah ukurannya

Urutan penggunaan yang lazim pada form baru adalah sebagai berikut.

  1. Tambahkan TableLayoutPanel lalu pasang Dock = DockStyle.Fill agar tabel mengisi seluruh form.
  2. Tentukan kolom dan baris beserta jenis ukurannya, misalnya kolom persen untuk konten dan baris AutoSize untuk masukan.
  3. Tempatkan kontrol ke selnya, beri Dock pada kontrol yang harus mengisi sel, dan atur Padding atau Margin untuk jarak.
  4. Gunakan Anchor untuk kontrol di luar tabel, misalnya tombol kecil pada sudut yang harus mengikuti tepinya.

Berkas berikut menerapkan urutan tersebut pada form daftar nama sederhana. Kode berjalan di Windows melalui Visual Studio atau dotnet run, sedangkan di lingkungan kerja tanpa layar, kode hanya diperiksa kompilasinya.

vb FormTataLetak.vb
' tidak-dijalankan
Imports System.Drawing
Imports System.Windows.Forms

Public Class FormTataLetak
    Inherits Form

    Private WithEvents inputNama As New TextBox()
    Private WithEvents tombolTambah As New Button()
    Private WithEvents daftarNama As New ListBox()
    Private tabel As New TableLayoutPanel()

    Sub New()
        Text = "Contoh Tata Letak"
        ClientSize = New Size(400, 220)

        tabel.Dock = DockStyle.Fill
        tabel.ColumnCount = 2
        tabel.RowCount = 2
        tabel.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
        tabel.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize))
        tabel.RowStyles.Add(New RowStyle(SizeType.AutoSize))
        tabel.RowStyles.Add(New RowStyle(SizeType.Percent, 100))
        tabel.Padding = New Padding(8)

        inputNama.Dock = DockStyle.Fill
        inputNama.PlaceholderText = "Nama baru"

        tombolTambah.Text = "Tambah"
        tombolTambah.Dock = DockStyle.Fill

        daftarNama.Dock = DockStyle.Fill

        tabel.Controls.Add(inputNama, 0, 0)
        tabel.Controls.Add(tombolTambah, 1, 0)
        tabel.Controls.Add(daftarNama, 0, 1)
        tabel.SetColumnSpan(daftarNama, 2)

        Controls.Add(tabel)
    End Sub

    Private Sub TombolTambahDiklik(sender As Object, e As EventArgs) Handles tombolTambah.Click
        Dim nama As String = inputNama.Text.Trim()
        If nama <> "" Then
            daftarNama.Items.Add(nama)
            inputNama.Clear()
        End If
    End Sub

End Class

Kolom pertama bertipe Percent sehingga menerima seluruh sisa lebar, sedangkan kolom kedua bertipe AutoSize yang lebarnya mengikuti tombol Tambah. Baris pertama AutoSize menyesuaikan tingginya dengan TextBox, dan baris kedua menerima sisanya untuk daftar nama. Ketika jendela diperlebar, hanya kolom persen dan baris persen yang tumbuh, sehingga tombol tidak ikut meregang tak terkendali.

Kesalahan umum#

Tiga kesalahan berikut paling sering muncul saat menata layout.

  1. Mengatur Location pada kontrol yang ter-dock. Nilainya diabaikan sistem penataan, sehingga kontrol terlihat berlawanan dengan aturan yang ditulis. Lepaskan Dock terlebih dahulu bila posisi bebas memang diinginkan.
  2. Menempatkan kontrol ke sel yang tidak ada, misalnya kolom ketiga pada tabel dua kolom. Pemanggilan Controls.Add(kontrol, kolom, baris) melempar ArgumentOutOfRangeException saat program berjalan. Sesuaikan ColumnCount dan RowCount sebelum menempatkan kontrol.
  3. Mencampur jangkar empat arah dengan sel TableLayoutPanel yang sudah meregangkan isinya. Dua mekanisme saling menarik dan hasilnya sulit diprediksi. Cukup Dock = DockStyle.Fill di dalam sel, dan simpan jangkar untuk kontrol di luar tabel.

Ringkasan#

  • Location dan Size bersifat tetap, sehingga form yang bergantung padanya rusak saat jendela diubah ukurannya.
  • Anchor menjaga jarak ke tepi terpilih, dan kombinasi empat arah dengan operator Or membuat kontrol meregang bersama jendela.
  • Dock menempelkan kontrol ke tepi dengan lebar penuh atau mengisi sisa ruang, sedangkan Location dan Size diabaikan selama ter-dock.
  • TableLayoutPanel membagi form menjadi baris dan kolom dengan ukuran Absolute, AutoSize, atau Percent, dan menjadi wadah utama sebelum Anchor digunakan di luar tabel.

Referensi#