Makale Özeti

Sadece rakam girilecek bir textboxınız olsaydı bazı işleriniz ne kadar kolay olurdu değilmi ? kullanıcı metinmi girmiş diye düşünmezdiniz, öyleyse hadi yapalım :)

Makale

C# ile Numeric TextBox Bileşeni 1

  

Merhabalar, bu makalemizde C# ile bir bileşen yaratacağız, ve bu bileşeni diğer Windows uygulamalarımızda kullanacak şekilde düzenleyeceğiz, ben uygulamayı WhidBey Beta 1 (Visual Studio 2005) ile yaptım, ama Vs.Net 2003 dede aynı kodları rahatlıkla çalıştırabilirsiniz.

 

İlk önce bu uygulamanın bağımsız bir şekilde çalışabilmesi için bir ClassLibrary oluşturalım, ben bu Class Librarynin adına NumericTextBox dedim

 

 

Böylece varsayılan olarak oluşturulan NameSpace nin adı NumericTextBox oldu, şimdi Classımızın adını düzeltelim ben bu Classın adına NumericTB yazdım. Esas önemli olan konu ise bu Classımızı hangi Classdan türeteceğimiz, .Net ile bir bileşen oluşturmanın 3 yöntemi vardır,

 

Windows Control Library tarzında bir proje oluşturarak birden çok kontrolü bir arayüzde (GUI) toplamak, buna kullanıcı kontrolüde deniliyor

Sıfırdan bir kontrolü komple yazmak, ancak bu çok kolay olan bir iş değildir, zira bir görsellik kazandırmak gibi işlemler oldukça çok vakit alır

 

Daha önceden oluşturulmuş bir kontrolü türeterek oluşturmak,

 

Biz üçüncü olan yöntemi kullanacağız, zaten TextBox gibi bir kontrol var, oturup bir daha TextBox tarzında bir kontrol yazmaya gerek yok, ben bu kontrolü türeterek istediğim gibi hükmedebilirim, işte .Net in gücü. Bunu yapmak için Class tanımımızdan hemen sonra “:” yi yerleştirip ondan hemen sonrada TextBox yazmamız gerekiyor, Ancak biz başlangıçta bir ClassLibrary şablonu seçip bundan projemizi oluşturduğumuz için TextBox un yer aldığı Classı burada kullanamayacağız, bunun için Referanslara System.Windows.Forms NameSpace sini eklememiz gerekiyor, en yukarıyada using deyimini yazmayı unutmayın. using System.Windows.Forms

 

 

    public class NumericTB:TextBox

    {}

 

Şimdi ilk olarak bu class ımızın kurucu metodu olan metodu oluşturalım. Biliyoruzki C# da kurucu metot Class ile aynı isimde olan metottur. Şimdi oluşturduğumuz bu kurucu metodu bizim inherit ettiğimiz (base) class ın base classını çağırarak kullanalım,

 

    public NumericTB():base()

    {}

 

Ben bu kodu yazmakla Class ımı türettiğim classın, kurucu metodunu çağırıyorum. Kurucu metotlar genellikle Class lar ın ilk instance ları alındığında çalışarak, Class ların içindeki değişkenlere (data member) başlangıç değerlerini atamak için kullanılırlar. Ben TextBox classından türettiğim kendi Classım için de bu işleri yapmak zorundaydım ancak  ben Base classımdaki kurucu metodu çağırarak bu işi yapmıyorum, benim yerime Base class taki metot bu işi yapıyor.

 

şimdi yapacağımız iş TextBox ın en çok kullandığımız özelliklerinden birisi olan Text Properties ini ezip onun yerine kendi yeni Text properties imizi yazmak olacak. Bunun için Visual Studio 2005 de public override yazdıktan sonra otomatik olarak property ler listeleniyor Text i seçip entere bastığınızdada aşağıdaki gibi bir kod ekranı oluşuyor.

 

 

public override string Text

{

      get

      {

            throw new global::System.NotImplementedException();

      }

 

      set

      {

            throw new global::System.NotImplementedException();

      }

}

 

Public bir Access Modifier yani bir erişim denetleyici, override ise daha önceden yazılmış bir metodun ezilmesini sağlayan bir keyword, yani benim Inherit ettiğim Class da bu isimli bir Property var ve eğer bu property çağarılır ise benim yazdığım property çalışsın Inherit ettiğim Class ın propertysi çalışmasın demek. Eğer siz bir değer girmezseniz yada burada oluşturulan throw new deyimlerini kaldırmazsanız otomatik olarak hata üretilmesini sağlayacak, bu yüzden bu oluşturulmuş olan throw new deyimlerini comment leyip aşağıdakı şekilde düzenleyin.

 

public override string Text

{

      get

      {

            return base.Text + " TL.";

            //throw new global::System.NotImplementedException();

      }

 

      set

      {

            base.Text = value;

            //throw new global::System.NotImplementedException();

      }

}

Bu kodları yazmakla şu işi yapmış oldum, bu kendi özel TextBox ım olduğu için Text değerini görmek istediklerinde otomatik olarak sonuna “TL.” yazısının eklenmesini sağladım, buradaki amaç aslında sadece bir property nin nasıl ezildiğini anlatmaktı. Daha farklı şeyler kullanabilirsiniz, örneğin bu benim özel olarak geliştirdiğim sadece Rakam girilebilecek bir TextBox olduğu için ben varsayılan olarak arka plan rengini açık mavi yapmak istiyorum, böylece kullanıcılar benim programımlarımı kullanırken açık mavi gördükleri TextBox lara sadece rakam girilebileceğini anlayacaklar, bu işi yapabilmek için aslında bu TextBox ilk oluşturulduğunda bu işlemin yapılmasını sağlamak gerekiyor bu yüzden ben bu işlemin kurucu metotta yapılmasını sağlamalıyım, Renkleri kullanabilmek için uygulamanıza System.Drawing i referans olarak eklemeniz gerekiyor, deminki yöntemle refenraslara System.Drawing i ekleyin. Ve kurucu metodu aşağıdaki gibi düzenleyin.

 

public NumericTB():base()

{

      base.BackColor = System.Drawing.Color.LightBlue;

}

 

 

Böylece her bu TextBox ı kullandığınızda TextBox ınızın arka plan rengi açık mavi olarak gelecek, beyaz değil.

 

Şimdi esas işimizi yapıp TextBox ın sadece rakamları kabul etmesini sağlamalıyız, bunun için ilk mantık olarak klavyenin tuşlarına basılma olaylarını bilmek gerekiyor, temel olarak üç adet klavyenin tuşlarını dinleyen olay var,

  • KeyUp
  • KeyDown
  • KeyPress

KeyUp olayı, klavyenin tuşuna siz basar basmaz tetiklenir ve çalışmaya klavyenin tuşuna siz basar basmaz başlar.

KeyDown olayı, klavyeden bir tuşa bastığınızda çalışmaz, tuştan parmağınızı çektiğinizde çalışmaya başlar. KeyUp ile farkı, birisi basılır basılmaz çalışır, diğeri basılıp tuşu bırakınca çalışır

KeyPress olayı, bu iki durumun sağlanması durumunda çalışır, yani basıp kaldırma işlemi gerçekleştiğinde çalışır.

Kategorize etmek gerekirse, KeyUp ile KeyDown aynı türden argümanlar türetirler, KeyPress ise bu ikisine göre daha farklı türden bir argüman üretir.

Biz uygulamamızda KeyPress i kullanacağız çünkü bize gönderdiği argüman (olay prosedürlerinde gelen iki argümandan birisi olan e argümanı) bizim işlerimizi daha kolay yapmamıza yarayacak, yapacağımız işi şöyle düşünelim, ben 0 ile 9 arasında bazı rakamların girilmesini istiyorum bunun dışındaki rakamlar girilmesin istiyorum tek tek bütün rakamları kontrol edeceğime bu rakamların ASCII kodlarını kontrol ederek bu işi çok kolay bir şekilde yapabilirim, çünkü ASCII kodlar belli bir mantıkta sıralanmış şekilde bulunurlar ve rakamsal olarak tutulurlar, örneğin 0 ın ASCII kodu 48, 9 un ASCII kodu 57 dir, diğer rakamlarda bu sırada yer alacak şekilde tasarlanmışlardır. Bunun dışında örneğin BackSpace nin ASCII karşılığı 8, Enter ın ASCII karşılığı ise 13 dür.

Hangi Karakterin karşılığının ne olduğunu öğrenmek istiyorsanız, formunuza bir TextBox yerleştirip aşağıdaki kodu yazarak denemelerinizi yapabilirsiniz.

 

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)

{

      MessageBox.Show(((int)e.KeyChar).ToString());

}

 

Böylece benim ihtiyacım olan aralığı bulmuş oldum, benim istediğim kullanıcı sadece ASCII kodu 48 ile 57 arasındaki karakterleri girebilsin ve birde silmek isterse ASCII kodu 8 olan tuşa basabilsin.

 

Şimdi aslında yapacağımız iş bizim yeni oluşturduğumuz TextBox ın bir olayını ezmek, bunu yapabilmek için ise protected override void OnKeyPress metodunu ezmemiz gerekiyor, buradaki önemli nokta, temelde her olayın aslında en az bir tane metodu tetiklediği, bizim KeyPress olayımız ise OnKeyPress metodunu tetikler ve olay gerçekleştiğinde bu metodu çalıştırır. Aşağıdaki kodları NumericTB classınıza ekleyin.

 

protected override void OnKeyPress(KeyPressEventArgs e)

{

      if ((int)e.KeyChar >= 47 && (int)e.KeyChar <= 58)

      {

            e.Handled = false;

      }

      else if ((int)e.KeyChar == 8)

      {

            e.Handled = false;

      }

      else

      {

            e.Handled = true;

      }

      //throw new NotImplementedException();

}

 

Burada yaptığım iş e ile gelen karakterin ASCII koduna bakıp bu ASCII karakterin 48 ile 57 arasında olup olmadığını inceliyorum, eğer bu aralıktaysa e.Handled özelliğini false yapıyorum böylece girilen rakam TextBox a yazılıyor, else if bölümü ilede girilen karakterin backspace (silme tuşu) olup olmadığına bakıyorum, silme tuşunun ASCII kodunun 8 olduğunu az önce bulmuştuk. Eğer 8 ise bu karakterinde TextBox a yazılmasını yani yazılan rakamın solundaki rakamın silinmesini sağlıyorum. Bunun dışında basılan karakter ne olursa olsun e.Handled ı true yapıyorum ve bu karakterin TextBox a girilmemesini sağlıyorum. Bu yazının ikinci bölümünde ise bu bileşeni strong name ile işaretleyip bir shared assembly yapıp istediğimiz uygulamalarda nasıl kullanabileceğimizi, toolBox daki görüntüsünü nasıl düzenleyebileceğimizi, propertylerini nasıl oturtabileceğimizi inceleyeceğiz.

 

 

Bu makale ile ilgili herhangi bir sorunuzda aşağıdaki mail adresimi kullanabilirsiniz.

 

Levent Cenk Çağlar

cenkc@yazgelistir.com