Custom Control Oluşturmak 3: Klasör Görüntüleyici (TreeView)
Selam dostlar! Sanırım, bu başlığı okuduktan sonra, kesin “şişman adam’ın TreeView’a karşı takıntısı var” diye düşüneceksiniz. Tamam kabul ediyorum. Şu ListDisplay kontrollere karşı büyük sempatim var. Hem kullanması hem de (elbette) kodlaması çok eğlenceli.
Şimdi; dostlarım, bundan önceki iki makalemde de User Control dediğimiz teknikle kendi kontrollerimizi geliştirmiştik. Bu kez, Derived Control (türemiş kontrol) tekniğiyle kendi kontrolümüzü yazıyor olacağız. Bu noktada koda geçmeden önce şu soruyu cevaplamaya çalışalım; “neden user control tekniği yerine derived control’ü seçeyim?” Benim bu konuda söyleyebileceğim tek bir şey var. Derived Control tekniğinde, kontrolünüzü .NET Framework’un System.Windows.Forms kütüphanesinde yer alan bir kontrolden türetiyorsunuz. Böylece kontrolünüz, aslında daha önce var olan bir kontrolün bir adım daha gelişmiş versiyonu olabiliyor.
Birazdan yazacağımız kontrol, belirtilen sürücü altındaki klasörleri kendi içinde listeleyen bir TreeView. Biz buna DirectoryControl diyelim. Öncelikle Bir Windows Application Projesi açalım ve bu projeye DirectoryControl.cs isminde bir class ekleyelim. Ve elbette bu classı, TreeView’ dan türetelim.
Ardından da ilk metodumuzu (Doldur()) yazmaya başlayalım. Bu metot, kontrolümüzü alt klasörlerle dolduracak olan metottur.
public class DirectoryControl : TreeView { private void Doldur(TreeNode klasorNode) { //Öncelikle parametrede belirtilen TreeNode'un fullPath özelliğinden yararlanarak DirectoryInfo nesnesini oluşturuyorum. Burada FullPath özelliği ParentNode'lar ile ChildNodelar arasına (/) işareti koyarak bulunduğu yeri gösteren bir özelliktir. DirectoryInfo klasor = new DirectoryInfo(klasorNode.FullPath); //Şimdi alt klasörlerde gezelim foreach (DirectoryInfo altKlasor in klasor.GetDirectories()) { //Burada try-catch bloğu kullanmamın sebebi şu; bazı sistem klasörleri okunamaz. try { TreeNode yeniNode = new TreeNode(altKlasor.Name); klasorNode.Nodes.Add(yeniNode); yeniNode.Nodes.Add("*"); } catch { } }
Kontrolümüzün çalışabilmesi için bir sürücü bilgisine ihtiyaç duyacağını daha önce belirtmiştik. Öyleyse bu ihtiyacı gidermek amacıyla bir özellik ve bu özelliğin Run-Time’da değişebileceğini de hesaba katarak GoruntuyuYenile() metodunu yazalım:
private char surucu; public char Surucu { get { return surucu; } set { surucu = value; GoruntuyuYenile(); } } public void GoruntuyuYenile() { Nodes.Clear(); TreeNode anaNode = new TreeNode(surucu + @":\"); Nodes.Add(anaNode); Doldur(anaNode); Nodes[0].Expand(); }
Tamamdır. Şimdi, dikkat ettiyseniz Doldur() metodunda oluşturduğumuz her node’un altına “*” işareti koymuştuk. Bunun sebebi, kullanıcıyı o treeNode’un altında ChildNode’ların olduğu konusunda ikna etmek. Böylece, kontrol veriyi çektiği anda tüm node’lar dolu gözükecek. Ama aslında seçili node, expand edildikten sonra dolacak (lütfen kendinizi hilebaz gibi hissetmeyin. Eş zamanlı olarak sürücüdeki tüm klasörleri çekmek çok daha uzun sürerdi.). Öyleyse TreeNode’un expand edilmesi esnasında, “*” değerini temizleyerek, klasörleri doldurmalıyım. Bunun için TreeView’in OnBeforeExpand metodunu eziyorum:
protected override void OnBeforeExpand(TreeViewCancelEventArgs e) { base.OnBeforeExpand(e); if (e.Node.Nodes[0].Text =="*") { e.Node.Nodes.Clear(); Doldur(e.Node); } }
Peki, şimdi bir de eventimiz olsun. Bu event, seçilen klasörün adresini de argümanlarında tutabilsin. Öyleyse önce EventArgs’ımızı yazalım:
public class DirectoryEventArgs: EventArgs { public string KlasorAdresi { get; set; } }
Tekrar kontrolümüze dönüp eventimizi yazalım:
public delegate void KlasorSecildiEventHandler(object sender, DirectoryEventArgs e); public event KlasorSecildiEventHandler KlasorSecildi;
Bu eventi fırlatma işi de yine TreeView’de var olan metodlardan biriyle, OnAfterSelect metoduyla mümkün. Bu metodu da ezerek KlasorSecildi olayını fırlatıyorum:
protected override void OnAfterSelect(TreeViewEventArgs e) { base.OnAfterSelect(e); //Eğer KlasorSecildi olayı yakalanmışsa: if (KlasorSecildi != null ) { KlasorSecildi(this,new DirectoryEventArgs{ KlasorAdresi=e.Node.FullPath}); } }
Artık sıra geldi test aşamasına. Projemizin Form tasarım ekranına dönerek toolbox’ dan DirectoryControl’ ü (genellikle ToolBox’da en üstlerdedir. ) Formun üzerine sürükleyelim. Hemen ardından Properties penceresinden Surucu özelliğini ‘C’ olarak ayarlayalım. Ve işte testimizin sonucu:
Bir sonraki makalede görüşmek üzere.
Kodla iyi eğlenceler.
Türkay ÜRKMEZ
Abi sen tam bir eğlence adamısın. Ayrıca TreeView hastası olduğun çok belli. Ama yakışıklı kontrol olmuş bence kullanılır yani.
Bir gün hoca(3. tekil şahıs) derste olayı kontrol geliştirmek olan bir firmadan bahsetmiş ve şöyle bişey demişti :"Ulan orda çalışmak vardı..hede hödö…". Aaah ah diyorum başka da bişey demiyorum (bkz.Ekşi Özentiliği :))
Birde; http://www.csharptricks.com/Articles/WindowsExplorerTree/ adresindeki ücretsiz hazır hepsi bi arada bi komponent var. Afiyet olsun.
Artı, yorum yazarken ülke kısmı otomatik olarak Türkiye olan blog istiyoruz 🙂
Konu ile pek alakası yok fakat sitenizi google reader’a eklemeye çalışıyorum ama bir türlü kabul etmiyor.. Bu sorunu bir kaç sitede daha yaşamıştım.. Sorun ile ilgili bir cevap verebilirseniz sevinirim..
Kolay gelsin, iyi günler..