Makale Özeti

Bu makalemde sizlere programcılıkta özel bir yerinin olduğunu belirteceğim custom controller üzerine olacaktır. Makalemize başlamadan önce custom controllerin ne oldukları hakkında ön bir açıklama yapmayı uygun görüyorum.

Makale

Bir çoğumuz web veya windowsta uygulamalar geliştirirken microsoft tarafından tasarlanmış kontroller (textbox, combobox, dropdownlist, listbox vs) gibi kontrolleri kullanmışızdır. Genel manada düşünürsek bu kontroller olmasa özellikle windows form tabanlı projelerde hangi tür zorlukları yaşayabileceğimizi az çok tahmin edebiliriz J. Bazı zamanlar bizler programcı olarak geliştirmekte olduğumuz projedeki amaca göre bazı kontrollerin yetersiz kaldığını düşünebiliriz ve aklımızdan keşke şu kontrolde şu özellikte olsaydı hep aynı şeyi yazmak zorunda kalmazdım dediğiniz olmuştur. Normalde projede kullandığınız kodların bir çoğunu kontroller üzerinden yaptığınızı görürsünüz ve her projede aynı kodları yazmaktan bir gün gına geldiğini düşünebilirsiniz J Böyle durumlarda kendi custom controlünüzü oluşturup yazdığınız kodu bir kere yazıp bütün projelerinizde kullanabilirsiniz. Bu durum size hem zaman kazanımı hemde aşırı kod yazma derdinden kurtaracaktır. Günümüzde sadece bu tarz kontroller oluşturup yazılım firmalarına ve yazılımcılara satan bir çok yabancı firma kurulmuştur. (Niye yerli yok dediğinizi hisseder gibiyim :D inşallah yakında olur ) Bu firmaların gayesi projelerimizde kullanabileceğimiz şık ve fonksiyonel kontroller oluşturup ihtiyaç sahiplerine satmak.

Ön açıklamamızı yaptıktan sonra eğitim amaçlı kontrolümüzü yazmaya başlayalım. Şöyle bir senaryomuz olsun. Elimde bir windows projesi var yaklaşık yirmi adet formum var ve her bir formumda ortalama on adet textbox nesnem mevcut. Formda verileri girerken bazı bölgelerde kesinlikle sayısal değerlerin girilmesini, bazı bölgelerde sadece karakter girilmesini istiyorum. Ayrıca seçtiğim textbox nesnesinin renginin sarı olmasını, başka bir nesneye aktif olduğumda eski halini almasını, ayarladığım takdirde mousenin üzerine gelindiğinde renginin değişmesini ve tekrar eski haline dönmesini istiyorum J. Oldukça zahmetli görünüyor. Normalde bu tarz bir durumu yapmak için tanımladığınız her textbox için ayrı ayrı olaylar yazmak, yada teker teker eventlerini tanımlamak gerekiyor. Bu hem zaman kaybı, hem gereksiz kod, hemde boşa emek harcamak diyebiliriz. Gelin bunu bir kontrol olarak geliştirelim ve projemize entegre ederek klasik textbox yerine bu nesnemizi kullanalım tüm ayarlarımızıda propertylerden ayarlayalım. Herşey otomatik olsun. Projemiz için Visual Studio 2005 C# editörümüzü açalım ve yeni bir Windows Control Library oluşturalım. Projemizin adı SuperTextBox olsun.

Projemizi ilk açtığımızda karşımıza klasik boş bir tanımlama formu çıkacak. Karşımıza çıkan bu form UserControl kalıtımından gelmektedir. Makalemizin konusu custom control olduğu için kalıtımın (Inheritance) üzerinde fazla durmayacağım ancak ne olduğunu bilmeyen arkadaşlarımız varsa bu konunun hakkında özellikle durmalarını ve araştırmalarını tavsiye etmek zorundayım. Ama kısaca açıklamak gerekirse. Daha önceden oluşturulmuş bir nesnenin (form, buton, liste vs) tüm özelliklerini alarak bize uygulama yapmamıza olanak tanıyan nesne yönelimli programlama tekniklerinin en güzel özelliklerinden birisi diyebiliriz. Projemizi açtığımızda karşımızda şöyle bir form görünümü oluşacaktır.

Bu noktada kontrol yapmamın iki yolu olabilir ilk yol UserControl objesinin kalıtımını kullanarak formun içerisine textbox nesnesini koymak ve kodlamak ama böyle bir durumda, nesnemizi projeye ekleyeceğimiz zaman çeşitli sorunlar çıkabilir. Örneğin direk oluşturduğumuz bileşene ulaşamayabiliriz yada ulaşmak için extra kod yazmamız gerekebilir. Yada boyutları ayarlarken çeşitli sorunlar yaşayabiliriz. Ben şahsen eğer sadece bir kontrol oluşturulacaksa bu yolla yapılmasını önermem ama yapanlarada saygı duyarım. İkinci yolumuz ise herhangi bir objenin kalıtımı olmadan, sadece var olan textbox nesnemizi kalıtım alarak klasik textbox nesnemizin bütün özellikleri üzerinden geliştirme yapmak. Böyle bir durumda hiçbir engelle karşılaşmayacağız. Öncelikle aşağıdaki kodu girelim.

Yukarıdaki kodumuzu biraz açıklayalım, soru işareti varsa giderelim. SuperTextBox adında isim uzayımızı (namespace) tanımladık. Nesnemizin classının adı SuperTextBox kalıtım olarak TextBox nesnesini almaktadır. Böylece Frameworkün System.Windows.Forms kütüphanesindeki textbox nesnesinin bütün özelliklerine sahip olmuş olduk. Projemizi derlemeden önce ana designer kod bölgesinden daha önceki nesnenin özelliklerini barındıracak herhangi bir kod varsa silelim aksi takdirde hata alabiliriz. Bahsettiğim kod şu şekilde olabilir

Altı çizili olan bölgeyi yada önceki tanımlı olan nesnenin silinmesiyle hata giderilecektir. Programımızı derlediğimizde herhangi bir sorun çıkmayacaktır. Ancak designere gittiğinizde SuperTextBox nesnesi görünmeyecektir. Çünkü kalıtım aldığımız nesne bir Windows Formu değil sadece textbox nesnesi. Bu yüzden ancak projede görünecektir.

Senaryomuzu daha önce söylemiştik. İlk olarak girdiğimiz bilginin numeric yani sayısal olmasını sağlayan ve aksi takdirde giriş yapılmasını engelleyecek olan özelliğimizin propertysi için bir bool tipinde bir değişken tanımlayalım, değerinede herhangi bir durumun olmaması için şimdilik false (aktif dışı) yapalım ve ardından da propertysini tanımlayalım.

Değerimizi hafızada tutacak olan bölümü yazmış olduk. Sıradaki bu özelliğimizi programın çalıştığı anında klavyeden basılacak tuş zamanında textbox nesnesinin event’ini (olay) çalıştırarak kontrol ettirmek ve seçilen değere göre numeric olup olmadığını kontrol edip müdahale etmek. Bunun içinde şöyle bir kod yazalım.

Bu kodları bilen arkadaşlarımız olabilir fakat ben bilmeyenler için anlatmayı uygun görüyorum. İlk başta tanımladığımız bool tipinde değişkeni ve propertiesini hatırlıyorsunuzdur. Burada if bloğuna sokulan bu değerdir. Eğer değer true ise bu değer kullanıcı tarafından değiştirilmiş ve girilen verilerin sayısal olmasını, karakterlerin engellenmesi isteniyor demektir. Böylece bir alt bloğa geçmektedir. Bir alt blokta klavyede girilen tuşun değeri e değişkeninde tutulmaktadır. Bu yüzden e değişkenini int türüne çeviriyoruz ve KeyChar özelliğinden klavyeden girilen değerine bakıyoruz girilen ascii değer 47 ile 58 arasında ise bunun sayısal değer olduğunu belirtip klavyenin tuşlarını yazmaya açıyoruz. Hemen altındaki blokta ise ikinci bir koşul olarak ascii karakterde 8 eşitse yani kullanıcı yazdığı rakamları backspace tuşuna basıp geriye doğru silmek isterse, bu durumun gerçekleşmesi için bu durumumuzu tanımlıyoruz. Bunlardan herhangi bir durum olmadığından girilen değer daima string yani karakter cinsinden görülüyor ve bu durumda da Handled özelliğinden klavye tuşlarını kapatıyoruz. Programımızı derlediğimizde. İlk özelliğimizi atamış olacağız. Artık numeric değerleri kontrol eden bir nesnemiz mevcut. Sıradaki özelliğimiz karakter girişi olsun. Takip edeceğimiz yol neredeyse aynısı sadece girilen ascii değerin 47 den küçük ve 57 den büyük olmasını kontrol ettirmemiz gerek. Önce yine ilk seferki gibi değişkenimizi ve propertiesimizi tanımlıyoruz. Kodumuz aşağıdaki gibidir.

Sıradaki olayımız sayısal veri girişini engellemek, toplam kod bloğumuz aşağıdaki gibidir.

Kısaca bir açıklama yapmamız gerekirse. KeyPress olayı yani klavyeden herhangi bir tuşa tıklandığında event tetiklenecek ve characteron adlı değişkenimizi kontrol edecek, değer eğer true ise girilen değerin ascii kodu okunarak bu sefer daha önce yaptığımızın tersini yaparak sadece karakter girilmesini sağlayacak. Hepsi bu kadar. Programımızı derlemeden önce kontrolün event (olay) değerlerinin atanmış olmasına dikkat edelim ve daha sonra programımızı derleyelim.

Kontrolümüz artık numeric ve karakter değerlerine karşı duyarlıdır. Sadece proje esnasında hem numeric hemde karakter özelliklerinin true olmamasına dikkat edelim J. Sıradaki özelliklerin daha da hoşunuza gidebileceğini düşünüyorum. Senaryosunu şöyle tanımlayalım. İki tane Color tipinde değişken tanımlayacağız. Bu değerler eğer kullanıcı tarafından aktif edilmişse, nesnemiz aktif olduğunda yada terk edildiğinde nesnemize vereceğimiz renkleri hafızada tutmamıza yarayacak olan değişken tipleridir. Öncelikle değişkenlerimizi ve tabiî ki propertiylerimizi tanımlayalım. Tanımladıktan sonra şuana kadar yaptığımız toplam değişkenler aşağıda ki gibi olacaktır.

Property tanımlamalarımız ise…

Şeklinde olacaktır. Kısa açıklama olarak.

Değerlerimizi renk tipi olarak tutacağımızdan Color değerini uygun gördük ve property değerlerimizide buna göre verdik. İlk değişkenimiz adı üstünde Mouse objemizin üzerine geldiğinde devreye girecek olan değerimizi hafızada tutacaktır. İkincisi ise Mouse objemizden ayrıldığında devreye girecek ve kullanıcı hangi rengi ayarladıysa ona dönecektir. Property menümüzden kullanıcının bu özelliği aktif edebilmesi ve tekrar kapatabilmesi için true false değerini tutan fazladan bir değişkene ihtiyacımız oldu ve değişkenimize bool veri tipini verdik adına da aktive dedik.

SuperTextBox nesnemize, mouse ile tıklandığı an aktif olması gerekiyor. Bunun için supertextbox nesnemizin Enter eventini tetiklememiz gerekiyor. Buradaki amacımızı şöyle açıklayalım. Aktive adında tanımladığımız değişken eğer kullanıcı tarafından true değerine alınırsa, kullanıcı aktif olunduğunda daha önceden ayarlanan renklerde supertextbox nesnesinin arkaplan rengini değiştirmek istiyor demektir. Bu durumu kontrol etmek için textbox nesnemizin Enter eventini tetikliyoruz ve kullanıcı aktive değişkenini değiştirip değiştirmediğini kontrol ediyoruz.

Kodlarımızı tanımlarken mutlaka event olay değerlerini atamayı unutmayalım. Aksi takdirde olaylar tetiklenmeyeceği için herhangi bir hareketlilik olmayacaktır.

Kısaca şöyle açıklayalım. Eğer aktive değişkeni true değerinde ise kullanıcı aktif etmiş demektir. Bu durumda MouseOver color değeri aktif olacak seçildiğinde rengi değişecektir. Eğer değer false girilmişse herhangi bir olay olmayacaktır ve işlem boş geçilecektir. Aynı şekilde değer true girildiğinde mouseleave olayı da devreye girecek ve cursor supertextbox objemizden ayrıldığında Leave olayı canlanacak, mouseleaving değişkeninde ki color değişkeni devreye girecektir.

Sıradaki mouse üzerine gelindiğinde ve mouse ile terkedildiğinde olsun. Aslında diğer kodlarımızdan neredeyse hiç bir farkı yok. Sadece extradan bool tipinde MouseAktive adında bir değişken ve bir property tanımlıyoruz.

 

Mouse üzerindeyken değişken değerinin kontrol edilmesi ve duruma göre supertextbox nesnesinin renk değişmesi ve sabit kalması lazım. O zaman nesnemizin MouseMove, MouseLeave eventlerini tetiklememiz gerekmektedir. Adlarındanda anlaşılacağı gibi birisi mouse gezinirken, diğeride mouse terk ettiğinde.

Kodlarımızı tanımladıktan sonra yine aynı şekilde olaylarının(event) atandığına dikkat edelim ve projemizi derleyelim.

Hepimize geçmiş olsun kontrolümüzü geliştirmiş ve kullanımımıza hazır hale getirmiş olduk. İyi ama bu kontrolümüzü nasıl kullanacağız ve projemize nasıl ekleyeceğiz! Normalde proje derlendiği zaman, eğer geliştirdiğimiz bir kontrol nesnesiyse yukarıda derleme tablosunda gördüğünüz gibi bin\Debug klasörünün içerisinde SuperTextBox.dll adında bir kontrol oluşturulacaktır

 

Oluşturduğumuz bileşeni projemize eklememiz için, projemize referans etmemiz gerekiyor. Gelin bunu da size ufak bir uygulamada gösterelim.

Bileşenimizi eklememiz için en başta oluşturduğumuz gibi yeni bir solution oluşturalım. Proje adı olarak istediğiniz bir ismi verebilirsiniz. Ben projeme WindowsApplication adını verdim.

Projemiz oluştur ve karşımıza tertemiz sıfır diyebileceğimiz bir Windows formu çıktı. Projemizi referans edebilmemiz için Toolbox bölümünün üzerindeyken Mousemizin sağ tuşuna basalım ve Choose Items seçeneğini tıklayalım. Karşımıza aşağıdaki gibi bir pencere çıkacaktır.

Bileşenimizi bulmak için Browse butonuna basalım. Karşımıza çıkacak olan pencereden projemizin kaynak dll dosyası neredeyse oraya yönlendirelim ve dll dosyamızı seçelim ardındanda ok veya tamam yaparak projemize ekleyelim.

Son olarakta nasıl normal bir objemizi projeye ekliyorsak aynı şekilde Mouse ile tutup projemize çekelim. Projemizi çektiğimizde hemen property özelliklerine bakalım.

Bu iş bu kadar. Dikkat etmeniz gereken aynı anda CharacterOn ve NumericOn değerlerini true yapmamanız ve aynı şekilde Aktive, MouseAktive değerlerini true yapmamanız. Böylece bir makalemizin daha sonuna gelmiş olduk. Bu kontrol daha ileri seviyede geliştirilebilir, amacımız anlatmak olduğu için birkaç tane özellikle yetinmek durumunda kaldık. Hepinize iyi günler dilerim başka bir makalede görüşmek üzere J