Artikel ini berfokus pada cara menggunakan kontrol TreeView. Kontrol TreeView memiliki fungsi yang kaya dan dapat digunakan dalam banyak situasi. Ringkasan: Menjelaskan cara menambahkan fungsionalitas pengikatan data ke kontrol TreeView. Ini adalah salah satu dari serangkaian contoh pengembangan kontrol Microsoft Windows. Anda dapat membaca artikel ini bersamaan dengan artikel ikhtisar terkait.
Perkenalan
Jika memungkinkan, Anda harus memulai dengan kontrol siap pakai karena kontrol Microsoft® Windows® Forms yang disediakan mencakup begitu banyak pengkodean dan pengujian sehingga akan sia-sia jika mengabaikannya dan memulai dari awal. Berdasarkan hal ini, dalam contoh ini, saya akan mewarisi kontrol Windows Forms yang ada, TreeView, dan kemudian menyesuaikannya. Saat Anda mengunduh kode untuk kontrol TreeView , Anda juga mendapatkan contoh pengembangan kontrol tambahan, serta contoh aplikasi yang menunjukkan cara menggunakan TreeView yang disempurnakan dengan kontrol terikat data lainnya.
Merancang tampilan pohon pengikatan data
Untuk pengembang Windows, menambahkan pengikatan data ke kontrol TreeView adalah masalah umum, tetapi karena ada satu perbedaan besar antara TreeView dan kontrol lainnya (seperti ListBox atau DataGrid ) (yaitu, TreeView menampilkan data hierarki), kontrol dasar Fitur ini adalah belum didukung (yaitu, kami masih harus menggunakannya). Dengan adanya tabel data, jelas bagaimana menampilkan informasi tersebut dalam ListBox atau DataGrid , namun menggunakan sifat TreeView yang berlapis untuk menampilkan data yang sama tidaklah mudah. Secara pribadi, saya telah menerapkan banyak metode berbeda saat menampilkan data menggunakan TreeView , tetapi ada satu metode yang paling umum digunakan: mengelompokkan data dalam tabel berdasarkan bidang tertentu, seperti yang ditunjukkan pada Gambar 1.
Gambar 1: Menampilkan data di TreeView
Dalam contoh ini, saya akan membuat kontrol TreeView di mana saya bisa meneruskan kumpulan data datar (ditunjukkan pada Gambar 2) dan dengan mudah menghasilkan hasil yang ditunjukkan pada Gambar 1.
Gambar 2: Kumpulan hasil datar yang berisi semua informasi yang diperlukan untuk membuat pohon seperti yang ditunjukkan pada Gambar 1
Sebelum saya memulai pengkodean, saya membuat desain untuk kontrol baru yang akan menangani kumpulan data khusus ini, dan mudah-mudahan ini akan berfungsi untuk banyak situasi serupa lainnya. Tambahkan kumpulan grup yang cukup besar untuk membuat struktur hierarki menggunakan sebagian besar data datar, di mana Anda menentukan bidang pengelompokan, bidang tampilan, dan bidang nilai untuk setiap tingkat hierarki (salah satu atau semua bidang harus sama). Untuk mengubah data yang ditunjukkan pada Gambar 2 menjadi TreeView yang ditunjukkan pada Gambar 1, kontrol baru saya mengharuskan Anda untuk menentukan dua tingkat pengelompokan, Publisher dan Title, dan mendefinisikan pub_id sebagai bidang pengelompokan grup Publisher dan title_id sebagai bidang pengelompokan dari grup Judul. Selain bidang pengelompokan, Anda juga perlu menentukan bidang tampilan dan nilai untuk setiap grup guna menentukan teks yang ditampilkan pada simpul grup terkait dan nilai yang secara unik mengidentifikasi grup tertentu. Saat menemukan data seperti ini, gunakan pub_name/pub_id dan title/title_id sebagai kolom tampilan/nilai untuk kedua grup ini. Informasi penulis menjadi simpul daun pohon (simpul di akhir hierarki pengelompokan), dan Anda juga perlu menentukan bidang ID ( au_id ) dan tampilan ( au_lname ) untuk simpul ini.
Saat membuat kontrol khusus, menentukan bagaimana pemrogram akan menggunakan kontrol sebelum memulai pengkodean akan membantu membuat kontrol lebih efisien. Dalam hal ini, saya ingin programmer (mengingat data yang ditampilkan sebelumnya dan hasil yang diinginkan) dapat melakukan pengelompokan dengan beberapa baris kode seperti ini:
Dengan DbTreeControl .ValueMember = au_id .DisplayMember = au_lname .DataSource = myDataTable.DefaultView .AddGroup(Penerbit, pub_id, nama_pub, pub_id) .AddGroup(Judul, title_id, title, title_id) Akhiri Dengan |
Catatan: Ini bukan baris kode terakhir yang saya tulis, tetapi serupa. Saat mengembangkan kontrol, saya menyadari bahwa saya perlu mengaitkan indeks gambar di ImageList yang terkait dengan TreeView dengan setiap tingkat pengelompokan, jadi saya harus menambahkan parameter tambahan ke metode AddGroup .
Untuk benar-benar membangun pohon, saya akan menelusuri data dan mencari perubahan pada bidang (ditentukan sebagai nilai pengelompokan untuk setiap pengelompokan) sambil membuat node pengelompokan baru jika perlu dan node daun untuk setiap item data. Karena pengelompokan node, jumlah total node akan lebih besar dari jumlah item di sumber data, namun akan ada tepat satu node daun untuk setiap item di data pokok.
Gambar 3: Node grup dan node daun
Perbedaan antara simpul daun dan simpul grup (ditunjukkan pada Gambar 3) akan menjadi penting untuk sisa artikel ini. Saya memutuskan untuk memperlakukan kedua jenis node ini secara berbeda, membuat node khusus untuk setiap jenis node, dan memunculkan peristiwa berbeda berdasarkan jenis node yang dipilih.
Menerapkan pengikatan data
Langkah pertama dalam menulis kode untuk kontrol ini adalah membuat proyek dan kelas awal yang sesuai. Dalam contoh ini, pertama-tama saya membuat Windows Control Library baru, lalu menghapus kelas default UserControl dan menggantinya dengan kelas baru yang mewarisi kontrol TreeView :
Kelas Publik dbTreeControl
Mewarisi System.Windows.Forms.TreeView
Mulai saat ini, saya akan merancang kontrol yang dapat ditempatkan pada formulir dan memiliki tampilan serta fungsionalitas TreeView biasa. Langkah selanjutnya adalah mulai menambahkan kode yang diperlukan untuk menangani fungsionalitas baru yang ditambahkan ke TreeView , yaitu data binding dan pengelompokan data.
Tambahkan properti DataSource
Semua fungsi kontrol baru saya penting, namun dua masalah utama dalam membangun kontrol terikat data yang kompleks adalah menangani properti DataSource dan mengambil item individual dari setiap objek di sumber data.
Buat atribut rutin
Pertama, kontrol apa pun yang digunakan untuk menerapkan pengikatan data yang kompleks perlu menerapkan rutinitas properti DataSource dan memelihara variabel anggota yang sesuai:
m_DataSource Pribadi Sebagai Objek _ Sumber Data Properti Publik() Sebagai Objek Mendapatkan Kembalikan m_DataSource Akhir Dapatkan Set (Nilai ByVal Sebagai Objek) Jika Nilai Bukan Apa-apa, Maka cm = Tidak ada Pengelompokan Berubah() Kalau tidak Jika Tidak (Nilai TypeOf Adalah IList Atau _ TypeOf Value Adalah IListSource) Lalu ' bukan sumber data yang valid untuk tujuan ini Lempar System.Exception Baru (Sumber Data Tidak Valid) Kalau tidak Jika TypeOf Value Adalah IListSource Lalu Redupkan myListSource Sebagai IListSource myListSource = CType(Nilai, IListSource) Jika myListSource.ContainsListCollection = Benar, Maka Lempar System.Exception Baru (Sumber Data Tidak Valid) Kalau tidak 'Ya, ya. ini adalah sumber data yang valid m_DataSource = Nilai cm = CType(Me.BindingContext(Nilai), _ Manajer Mata Uang) Pengelompokan Berubah() Akhiri Jika Kalau tidak m_DataSource = Nilai cm = CType(Me.BindingContext(Nilai), _ Manajer Mata Uang) Pengelompokan Berubah() Akhiri Jika Akhiri Jika Akhiri Jika Kumpulan Akhir Properti Akhir |
Objek yang dapat digunakan sebagai sumber data untuk pengikatan data kompleks umumnya didukung. Antarmuka ini memaparkan data sebagai kumpulan objek dan menyediakan beberapa properti berguna, seperti Count . Kontrol TreeView baru saya memerlukan objek yang didukung IList dalam pengikatannya, tetapi menggunakan antarmuka lain berfungsi dengan baik karena menyediakan cara mudah untuk mendapatkan objek IList ( GetList ). Saat menyetel properti DataSource , pertama-tama saya menentukan apakah objek valid disediakan, yaitu objek yang mendukung IList atau IListSource . Yang sebenarnya saya inginkan adalah IList , jadi jika objek hanya mendukung IListSource (mis. DataTable ), maka saya akan menggunakan metode GetList() dari antarmuka tersebut untuk mendapatkan objek yang benar.
Beberapa objek yang mengimplementasikan IListSource (seperti DataSet ) sebenarnya berisi beberapa daftar yang diwakili oleh properti ContentListCollection . Jika properti ini True , GetList akan mengembalikan objek IList yang mewakili sebuah daftar (berisi beberapa daftar). Dalam contoh saya, saya memutuskan untuk mendukung koneksi langsung ke objek IList atau objek IListSource yang hanya berisi satu objek IList , dan mengabaikan objek yang memerlukan pekerjaan tambahan untuk menentukan sumber data, seperti DataSet .
Catatan: Jika Anda ingin mendukung objek tersebut ( DataSet atau serupa), Anda dapat menambahkan properti tambahan (seperti DataMember ) untuk menentukan sublist tertentu untuk pengikatan.
Jika sumber data yang diberikan valid, hasil akhirnya adalah instance yang dibuat ( cm = Me.BindingContext(Value) ). Karena instance ini akan digunakan untuk mengakses sumber data pokok, properti objek, dan informasi lokasi, maka instance ini disimpan dalam variabel lokal.
Tambahkan properti anggota tampilan dan nilai
Memiliki DataSource adalah langkah pertama dalam menerapkan pengikatan data yang kompleks, namun kontrol perlu mengetahui bidang atau properti data mana yang akan digunakan sebagai anggota tampilan dan nilai. Anggota Tampilan akan digunakan sebagai judul simpul pohon, sedangkan anggota Nilai dapat diakses melalui properti Nilai simpul. Semua properti ini adalah string yang mewakili nama bidang atau properti dan dapat dengan mudah ditambahkan ke kontrol:
m_ValueMember Pribadi Sebagai String m_DisplayMember Pribadi Sebagai String _ ValueMember Properti Publik() Sebagai String Mendapatkan Kembalikan m_ValueMember Akhir Dapatkan Set (Nilai ByVal Sebagai String) m_ValueMember = Nilai Kumpulan Akhir Properti Akhir _ Properti Publik DisplayMember() Sebagai String Mendapatkan Kembalikan m_DisplayMember Akhir Dapatkan Set (Nilai ByVal Sebagai String) m_DisplayMember = Nilai Kumpulan Akhir Properti Akhir |
Dalam TreeView ini, properti ini hanya akan mewakili anggota Display dan Value dari node daun, dan informasi terkait untuk setiap tingkat pengelompokan akan ditentukan dalam metode AddGroup .
Menggunakan objek CurrencyManager
Dalam properti DataSource yang dibahas sebelumnya, sebuah instance dari kelas CurrencyManager dibuat dan disimpan dalam variabel tingkat kelas. Kelas CurrencyManager yang diakses melalui objek ini adalah bagian penting dalam penerapan pengikatan data karena memiliki properti, metode, dan peristiwa yang mengaktifkan fungsi berikut:
Ambil atribut/nilai bidang
Objek CurrencyManager memungkinkan Anda mengambil nilai properti atau bidang, seperti nilai bidang DisplayMember atau ValueMember , dari item individual di sumber data melalui metode GetItemProperties . Kemudian gunakan objek PropertyDescriptor untuk mendapatkan nilai bidang atau properti tertentu pada item daftar tertentu. Cuplikan kode berikut menunjukkan cara membuat objek PropertyDescriptor ini dan cara menggunakan fungsi GetValue untuk mendapatkan nilai properti item di sumber data pokok. Perhatikan properti List pada objek CurrencyManager : properti ini menyediakan akses ke instance IList yang terikat dengan kontrol:
Redupkan myNewLeafNode Sebagai TreeLeafNode Redupkan currObject Sebagai Objek currObject = cm.Daftar(indeksDaftar saat ini) Jika Saya.DisplayMember <> Dan Juga Saya.ValueMember <> Lalu 'Tambahkan simpul daun? Redupkan pdValue Sebagai System.ComponentModel.PropertyDescriptor Redupkan pdDisplay Sebagai System.ComponentModel.PropertyDescriptor pdValue = cm.GetItemProperties()(Saya.ValueMember) pdDisplay = cm.GetItemProperties()(Saya.DisplayMember) myNewLeafNode = _ TreeLeafNode(CStr(pdDisplay.GetValue(currObject)) baru, _ objek saat ini, _ pdValue.GetValue(objek saat ini), _ Indeks Daftar saat ini) |
GetValue mengabaikan tipe data dasar properti saat mengembalikan objek, sehingga nilai yang dikembalikan perlu dikonversi sebelum menggunakannya.
Jaga agar kontrol yang terikat data tetap sinkron
CurrencyManager memiliki satu lagi fitur utama: selain menyediakan akses ke sumber data terikat dan properti item, ini memungkinkan DataSource yang sama digunakan untuk mengoordinasikan pengikatan data antara kontrol ini dan kontrol lainnya. Dukungan ini dapat digunakan untuk memastikan bahwa beberapa kontrol yang terikat pada sumber data yang sama pada saat yang sama tetap berada pada item sumber data yang sama. Untuk kontrol saya, saya ingin memastikan bahwa ketika sebuah item dipilih di pohon, semua kontrol lain yang terikat ke sumber data yang sama menunjuk ke item yang sama (catatan, baris, atau bahkan larik yang sama, jika Anda mau untuk berpikir dalam kaitannya dengan database). Untuk melakukan ini, saya mengganti metode OnAfterSelect di dasar TreeView . Dalam metode itu (yang dipanggil setelah memilih simpul pohon), saya mengatur properti Posisi objek CurrencyManager ke indeks item yang dipilih saat ini. Contoh aplikasi yang disediakan dengan kontrol TreeView mengilustrasikan bagaimana kontrol sinkronisasi mempermudah pembuatan antarmuka pengguna yang terikat data. Untuk mempermudah menentukan posisi daftar item yang dipilih saat ini, saya menggunakan kelas TreeNode khusus ( TreeLeafNode atau TreeGroupNode ) dan menyimpan indeks daftar setiap node ke dalam properti Position yang saya buat:
Sub Penggantian Terlindungi OnAfterSelect _ (ByVal dan Sebagai System.Windows.Forms.TreeViewEventArgs) Redupkan tln Sebagai TreeLeafNode Jika TypeOf e.Node Adalah TreeGroupNode Lalu tln = TemukanFirstLeafNode(e.Node) Redupkan groupArgs Sebagai groupTreeViewEventArgs baru(e) RaiseEvent AfterGroupSelect(groupArgs) ElseIf TypeOf e.Node Adalah TreeLeafNode Lalu Redupkan leafArgs Sebagai leafTreeViewEventArgs baru (e) RaiseEvent AfterLeafSelect(leafArgs) tln = CType(e.Node, TreeLeafNode) Akhiri Jika Jika Tidak, Tidak Ada Apa-apanya Jika cm.Posisi <> tln.Posisi Lalu cm.Posisi = tln.Posisi Akhiri Jika Akhiri Jika MyBase.OnAfterSelect(e) Akhiri Sub |
Pada cuplikan kode sebelumnya, Anda mungkin telah memperhatikan fungsi bernama FindFirstLeafNode , yang ingin saya perkenalkan secara singkat di sini. Di TreeView saya, hanya simpul daun (simpul terakhir dalam hierarki) yang sesuai dengan item di DataSource , semua simpul lainnya hanya digunakan untuk membuat struktur pengelompokan. Jika saya ingin membuat kontrol terikat data yang berkinerja baik, saya selalu perlu memilih item yang sesuai dengan DataSource , jadi setiap kali saya memilih simpul grup, saya menemukan simpul daun pertama di bawah grup, seolah-olah simpul ini adalah seleksi saat ini. Anda dapat melihat contoh tindakannya, tetapi untuk saat ini Anda bebas menggunakannya.
Fungsi Pribadi FindFirstLeafNode(ByVal currNode Sebagai TreeNode) _ Sebagai TreeLeafNode Jika TypeOf currNode Adalah TreeLeafNode Lalu Kembalikan CType(currNode, TreeLeafNode) Kalau tidak Jika currNode.Nodes.Count > 0 Lalu Kembalikan FindFirstLeafNode(currNode.Nodes(0)) Kalau tidak Kembalikan Tidak Ada Akhiri Jika Akhiri Jika Fungsi Akhir |
Menetapkan properti Posisi objek Mata UangManager menyinkronkan kontrol lain dengan pilihan saat ini, namun ketika posisi kontrol lain berubah, Mata UangManager juga menghasilkan peristiwa sehingga pilihan berubah sesuai. Untuk menjadi komponen terikat data yang baik, pilihan harus berpindah seiring perubahan lokasi sumber data, dan tampilan harus diperbarui ketika data untuk item diubah. Ada tiga event yang dimunculkan oleh CurrencyManager : CurrentChanged , ItemChanged dan PositionChanged . Peristiwa terakhir cukup sederhana; salah satu tujuan dari CurrencyManager adalah untuk mempertahankan indikator posisi saat ini untuk sumber data sehingga beberapa kontrol terikat semuanya dapat menampilkan catatan atau item daftar yang sama, dan peristiwa ini dimunculkan setiap kali posisi berubah. Dua peristiwa lainnya terkadang tumpang tindih dan perbedaannya kurang jelas. Berikut ini menjelaskan cara menggunakan peristiwa ini dalam kontrol khusus: PositionChanged adalah peristiwa yang relatif sederhana dan tidak akan dijelaskan di sini ketika Anda ingin menyesuaikan item yang dipilih saat ini dalam kontrol terikat data yang kompleks (seperti Pohon), silakan gunakan The peristiwa. Peristiwa ItemChanged dimunculkan setiap kali item di sumber data diubah, sedangkan CurrentChanged dimunculkan hanya ketika item saat ini diubah.
Di TreeView saya, saya menemukan bahwa setiap kali saya memilih item baru, ketiga acara dimunculkan, jadi saya memutuskan untuk menangani acara PositionChanged dengan mengubah item yang saat ini dipilih dan tidak melakukan apa pun dengan dua lainnya. Disarankan untuk mentransmisikan sumber data ke IBindingList (jika sumber data mendukung IBindingList ) dan menggunakan acara ListChanged sebagai gantinya, tetapi saya belum menerapkan fungsi ini.
Sub Pribadi cm_PositionChanged(Pengirim ByVal Sebagai Objek, _ ByVal e As System.EventArgs) Menangani cm.PositionChanged Redupkan tln Sebagai TreeLeafNode Jika TypeOf Me.SelectedNode Adalah TreeLeafNode Lalu tln = CType(Me.SelectedNode, TreeLeafNode) Kalau tidak tln = TemukanFirstLeafNode(Saya.SelectedNode) Akhiri Jika Jika tln.Posisi <> cm.Posisi Lalu Me.SelectedNode = FindNodeByPosition(cm.Position) Akhiri Jika Akhiri Sub Fungsi Kelebihan Beban Pribadi FindNodeByPosition (indeks ByVal Sebagai Integer) _ Sebagai TreeNode Kembalikan FindNodeByPosition(indeks, Me.Nodes) Fungsi Akhir Fungsi Kelebihan Beban Pribadi FindNodeByPosition (indeks ByVal Sebagai Integer, _ ByVal NodesToSearch Sebagai TreeNodeCollection) Sebagai TreeNode Redupkan saya Sebagai Integer = 0 Redupkan currNode Sebagai TreeNode Redupkan tln Sebagai TreeLeafNode Lakukan Sementara saya < NodesToSearch.Count currNode = NodesToSearch(i) saya += 1 Jika TypeOf currNode Adalah TreeLeafNode Lalu tln = CType(currNode, TreeLeafNode) Jika tln.Posisi = indeks Lalu Kembalikan CurrNode Akhiri Jika Kalau tidak currNode = FindNodeByPosition(indeks, currNode.Nodes) Jika Tidak currNode Bukan Apa-apa, Maka Kembalikan CurrNode Akhiri Jika Akhiri Jika Lingkaran Kembalikan Tidak Ada Fungsi Akhir |
Ubah DataSource menjadi pohon
Setelah menulis kode pengikatan data, saya dapat melanjutkan dan menambahkan kode untuk mengelola tingkat pengelompokan, membangun pohon yang sesuai, dan kemudian menambahkan beberapa peristiwa, metode, dan properti khusus.
Kelompok manajemen
Untuk mengkonfigurasi kumpulan grup, pemrogram harus membuat fungsi AddGroup , RemoveGroup , dan ClearGroups . Setiap kali kumpulan grup diubah, pohon harus digambar ulang (untuk mencerminkan konfigurasi baru), jadi saya membuat prosedur umum, GroupingChanged , yang dapat dipanggil dengan berbagai kode di kontrol ketika keadaan berubah dan pohon perlu dipaksa untuk dibangun kembali:
Grup Pohon Pribadi Sebagai ArrayList Baru() Sub Publik Hapus Grup (Grup ByVal Sebagai Grup) Jika Bukan treeGroups.Contains(group) Lalu treeGroups.Remove(grup) Pengelompokan Berubah() Akhiri Jika Akhiri Sub Sub Grup Tambahan Kelebihan Beban Publik (Grup ByVal Sebagai Grup) Mencoba treeGroups.Tambahkan(grup) Pengelompokan Berubah() Menangkap Akhiri Coba Akhiri Sub Sub Grup Tambahan Kelebihan Beban Publik (Nama ByVal Sebagai String, _ Grup ByValBy Sebagai String, _ ByVal displayMember Sebagai String, _ Nilai ByValMember Sebagai String, _ ByVal imageIndex Sebagai Integer, _ ByVal dipilihImageIndex Sebagai Integer) Redupkan myNewGroup Sebagai Grup Baru (nama, groupBy, _ anggota tampilan, anggota nilai, _ indeks gambar, indeks gambar yang dipilih) Saya.TambahkanGrup(GrupBaru saya) Akhiri Sub Fungsi Publik GetGroups() Sebagai Grup() Kembalikan CType(treeGroups.ToArray(GetType(Group)), Grup()) Fungsi Akhir |
pohon merentang
Rekonstruksi pohon sebenarnya dilakukan melalui sepasang proses: BuildTree dan AddNodes . Karena kode untuk kedua proses ini terlalu panjang, artikel ini tidak mencantumkan semuanya, tetapi mencoba merangkum perilakunya (tentu saja, Anda dapat mengunduh kode lengkapnya jika Anda mau). Seperti disebutkan sebelumnya, pemrogram dapat berinteraksi dengan kontrol ini dengan menyiapkan serangkaian grup, lalu menggunakan grup ini di BuildTree untuk menentukan cara menyiapkan node pohon. BuildTree menghapus kumpulan simpul saat ini dan kemudian mengulangi seluruh sumber data untuk memproses pengelompokan tingkat pertama (Penerbit disebutkan dalam contoh dan ilustrasi sebelumnya di artikel ini), menambahkan sebuah simpul untuk setiap nilai pengelompokan yang berbeda (menggunakan data dalam contoh, untuk setiap Tambahkan node dengan nilai pub_id ), lalu panggil AddNodes untuk mengisi semua node di bawah pengelompokan tingkat pertama. AddNodes memanggil dirinya sendiri secara rekursif untuk menangani level sebanyak yang diperlukan, menambahkan node grup dan node daun jika diperlukan. Gunakan dua kelas khusus berdasarkan TreeNode untuk membedakan simpul grup dan simpul daun, dan berikan atribut yang sesuai untuk kedua jenis simpul tersebut.
Acara TreeView khusus
Setiap kali sebuah node dipilih, TreeView memunculkan dua peristiwa: BeforeSelect dan AfterSelect . Namun dalam kendali saya, saya ingin membuat kejadian pada simpul grup dan simpul daun berbeda, jadi saya menambahkan kejadian saya sendiri BeforeGroupSelect/AfterGroupSelect dan BeforeLeafSelect/AfterLeafSelect . Selain kejadian dasar, saya juga memicu kelas parameter kejadian khusus:
Acara Publik SebelumGrupPilih _ (Pengirim ByVal Sebagai Objek, ByVal dan Sebagai groupTreeViewCancelEventArgs) Acara Publik AfterGroupSelect _ (Pengirim ByVal Sebagai Objek, ByVal dan Sebagai groupTreeViewEventArgs) Acara PublikBeforeLeafSelect _ (Pengirim ByVal Sebagai Objek, ByVal dan Sebagai leafTreeViewCancelEventArgs) Acara Publik AfterLeafSelect _ (Pengirim ByVal Sebagai Objek, ByVal dan Sebagai leafTreeViewEventArgs) Sub Penggantian Dilindungi Pada Sebelum Pilih _ (ByVal dan Sebagai System.Windows.Forms.TreeViewCancelEventArgs) Jika TypeOf e.Node Adalah TreeGroupNode Lalu Redupkan groupArgs Sebagai groupTreeViewCancelEventArgs baru(e) RaiseEvent BeforeGroupSelect(CObj(Saya), groupArgs) ElseIf TypeOf e.Node Adalah TreeLeafNode Lalu Redupkan leafArgs Sebagai New leafTreeViewCancelEventArgs(e) RaiseEvent BeforeLeafSelect(CObj(Saya), leafArgs) Akhiri Jika MyBase.OnBeforeSelect(e) Akhiri Sub Sub Penggantian Terlindungi OnAfterSelect _ (ByVal dan Sebagai System.Windows.Forms.TreeViewEventArgs) Redupkan tln Sebagai TreeLeafNode Jika TypeOf e.Node Adalah TreeGroupNode Lalu tln = TemukanFirstLeafNode(e.Node) Redupkan groupArgs Sebagai groupTreeViewEventArgs baru(e) RaiseEvent AfterGroupSelect(CObj(Saya), groupArgs) ElseIf TypeOf e.Node Adalah TreeLeafNode Lalu Redupkan leafArgs Sebagai leafTreeViewEventArgs baru (e) RaiseEvent AfterLeafSelect(CObj(Saya), leafArgs) tln = CType(e.Node, TreeLeafNode) Akhiri Jika Jika Tidak, Tidak Ada Apa-apanya Jika cm.Posisi <> tln.Posisi Lalu cm.Posisi = tln.Posisi Akhiri Jika Akhiri Jika MyBase.OnAfterSelect(e) Akhiri Sub |
Kelas simpul khusus ( TreeLeafNode dan TreeGroupNode ) dan kelas parameter peristiwa khusus disertakan dalam kode yang dapat diunduh.
Contoh aplikasi
Untuk memahami sepenuhnya semua kode dalam contoh kontrol ini, Anda harus memahami cara kerjanya di aplikasi Anda. Contoh aplikasi yang disertakan menggunakan database Access pubs.mdb dan mengilustrasikan bagaimana kontrol Pohon dapat digunakan dengan kontrol terikat data lainnya untuk membuat aplikasi Windows. Fitur utama dari catatan khusus dalam hal ini mencakup sinkronisasi pohon dengan kontrol terikat lainnya dan pemilihan otomatis node pohon saat melakukan pencarian pada sumber data.
Catatan: Contoh aplikasi ini (bernama TheSample) disertakan dalam unduhan untuk artikel ini.
Gambar 4: Aplikasi demo untuk TreeView yang terikat data
ringkasan
Kontrol Pohon terikat data yang dijelaskan dalam artikel ini tidak cocok untuk setiap proyek yang memerlukan kontrol Pohon untuk menampilkan informasi database, namun kontrol tersebut memperkenalkan metode untuk menyesuaikan kontrol untuk tujuan pribadi. Ingatlah bahwa kontrol terikat data kompleks apa pun yang ingin Anda buat akan memiliki banyak kode yang sama dengan kontrol Pohon, dan Anda dapat menyederhanakan pengembangan kontrol di masa mendatang dengan memodifikasi kode yang ada.