C Sharp Programlama Dili/Form tabanlı uygulamalar
C#'ta görsel formlarla ilgili işlemler System.Windows.Forms isim alanındaki sınıflarla yapılır. Bu isim alanı System.Windows.Forms.dll assemblysindedir.
Form sınıfı
değiştirForm sınıfı programımıza bir form getirmeye yarar. Örnek program:
using System.Windows.Forms;
class FormOrnek
{
static void Main()
{
Form f=new Form();
f.Show();
}
}
Bu programda önce bir komut satırı açılır, sonra bir form açılır, sonra form kapanır. Eğer sisteminiz çok hızlıysa formu görmemeniz bile mümkündür. Ancak program çalışacaktır. Şimdi bir de bu programı
csc /t:winexe form.cs
komutuyla derleyin. Bu durumda ilgili exe dosyasını çift tıklayıp açtığımızda artık komut satırı penceresi gözükmeyecektir. Yani /t:winexe
argümanının tek fonksiyonu budur. Şimdi program kodumuzu şöyle değiştirelim:
using System.Windows.Forms;
class FormOrnek
{
static void Main()
{
Form f=new Form();
Application.Run(f);
}
}
Bu sefer Form sınıfının Show() metodunu değil, Application sınıfının static Run() metodunu kullandık ve metodun parametresine Form nesnemizi verdik. Bu sefer form biz sağ üst köşedeki kapatma düğmesine basana kadar ekranda kalacaktır. Şimdi programızı şöyle değiştirelim:
using System.Windows.Forms;
class FormOrnek:Form
{
static void Main()
{
Application.Run(new FormOrnek());
}
}
Bu programda öncekilerin aksine Form sınıfına bağlanmadık. Kendi sınıfımızı Form sınıfından türettik. Bu sayede Form sınıfının birçok static üye elemanına yalnızca üye elemanın adını yazarak erişebiliriz. Ancak burada sınıfımızı Form sınıfından türetmedeki asıl amaç programımızın aslında bir form olmasıdır. Yani mantıksal bütünlüğü korumak için sınıfımızı Form sınıfından türettik.
NOT: Sinif a=new Sinif()
satırında nesneyi oluşturan asıl kısım new Sinif()
kısmıdır. Diğer kısım yalnızca oluşturulan bu nesnenin a referansına atanmasını sağlar.
Button sınıfı
değiştirDaha önce formun mantıksal olarak programımızın kendisini temsil ettiğini söylemiştik. Butonlar ve diğer kontroller ise yalnızca programımızdaki bileşenleri temsil ederler. Şimdi Button sınıfıyla ilgili bir örnek yapalım:
using System.Windows.Forms;
using System.Drawing;
class Form1:Form
{
private Button buton;
public Form1()
{
buton=new Button();
buton.Text="Butonun üzerindeki yazı";
buton.Location=new Point(50,50);
buton.Cursor=Cursors.No;
buton.Size=new Size(150,50);
this.Text="Formun başlığı";
this.Controls.Add(buton);
}
static void Main()
{
Application.Run(new Form1());
}
}
Size ve Point System.Drawing isim alanında bulunan iki sınıftır ve bir kontrolün konum ve boyut bilgisini tutarlar. Button sınıfının Location özelliği Point tipinden, Size özelliği ise Size tipindendir. Button sınıfının Text özelliği butonun üzerindeki yazıyı, Cursor özelliği fare ilgili butonun üzerine geldiğinde alacağı şekli belirtmemizi sağlar. Cursors enumu System.Windows.Forms isim alanındadır. Daha önceden de gördüğümüz gibi this anahtar sözcüğü bir yere hangi nesne üzerinden erişilmişse o nesneyi tutar. Form1 sınıfının yapıcı metoduna new Form1()
yazarak eriştiğimize göre bu yere yeni bir Form1 nesnesi üzerinden erişilmiştir. Form sınıfının Text özelliği formun başlık çubuğundaki başlığını belirtir. Form sınıfındaki Controls özelliğinin tipi yalnızca kontrolleri tutabilen bir koleksiyondur. Bu koleksiyona nesne eklersek aynı zamanda forma da kontrol eklemiş oluruz.
NOT: Nesne yönelimli programlamanın en temel yaklaşımı bir problemi olabildiğince çok parçaya bölüp her bir parçanın yalnızca kendisiyle ilgili kodlar içermesidir. Bu sayede kaynak kodun karmaşıklığı azalacak ve kodun yönetimi kolaylaşacaktır. Biz bu örneğimizde bütün kodları Main metodunun içine koyabilirdik. Ancak nesne yönelim tekniğinin temel yaklaşımına aykırı olurdu. Üstelik bu sayede kodumuzda mantıksal bir bütünlük de yakaladık. Örneğin buton, formumuzda bulunan bir bileşendir. Bunu Main ya da yapıcı metoda koymak yerine Form1 sınıfının bir özelliği olarak yerleştirdik. Benzer şekilde yapıcı metoda yalnızca formla ilgili kodlar yerleştirdik. Programımızın temel kısmı olan Main() metodumuz ise yalnızca ilgili metotları çağırmaktan başka işe yaramadı. Gelişmiş uygulamalarda Main() metodu olabildiğince az kod içerir. Main() metodu yalnızca diğer metotların koordinasyonuyla ilgilenir.
Olaylar ve formlar
değiştirHatırlarsanız Temsilciler ve Olaylar konusunda olayların Windows formlarıyla içli dışlı olduğunu söylemiştik. Olayların en yaygın kullanım yeri Windows formlarıdır. Windows formlarıyla ilgili sınıfların çoğunun onlarca olayı vardır. Bu olayların tipi EventHandler temsilcisidir. Bu temsilci şu şekildedir.
void EventHandler(object kaynak, EventArgs e)
Yani bu temsilci geriye bir değer döndürmeyen, iki parametre alan ve parametreleri de sırasıyla object ve EventArgs türünden olan metotları temsil eder. Dolayısıyla da Windows formlarıyla ilgili sınıfların olaylarına da yalnızca bu prototipte metotlar bağlanabilir. Hatırlarsanız olaylar konusunda hem temsilciyi (olay töneticisi), hem olayı, hem olaya bağlanan metodu biz yazmış, hatta olayı da biz gerçekleştirmiştik. Halbuki Windows formlarında biz yalnızca olaya bağlanan metotla ilgileniriz. Windows formlarında olay yöneticisi yukarıda prototipi yazılan EventHandler temsilcisidir. Yine bütün formlarla ilgili olaylar ilgili sınıfta bildirilmiştir. Olayın gerçekleştirilmesini ise kullanıcı yapar. İşletim sistemi herhangi bir olay gerçekleştiğinde (örneğin butonun tıklanması) olayın gerçekleştiği bilgisini ve bu olayla ilgili ek bilgileri programımıza verir. Eğer programımızda bu olayı işleyecek herhangi bir metot yoksa hiçbir şey yapılmaz. Varsa o metottaki komutlar çalıştırılır. Şimdi olayları hatırlama açısından bir örnek yapalım:
using System;
delegate void OlayYoneticisi(); //Olay yöneticisi bildirimi
class AnaProgram
{
static void Main()
{
AnaProgram nesne=new AnaProgram();
nesne.Olay+=new OlayYoneticisi(Metot); //Olay sonrası işletilecek metotların eklenmesi
nesne.Olay(); //Olayın gerçekleştirilmesi
}
//Olay sonrası işletilecek metot
static void Metot()
{
Console.WriteLine("Butona tıklandı.");
}
event OlayYoneticisi Olay; //Olay bildirimi
}
Bu en basit olay mantığıydı. Şimdi bunu Windows formlarına uyarlayalım:
delegate void EventHandler(object o,EventArgs e);
class Button
{
event EventHandler Click;
}
class KendiSinifimiz
{
static void Main()
{
Button buton1=new Button();
buton1.Click+=new EventHandler(Metot);
}
void Metot(object o,EventArgs e)
{
//Tıklandığında çalışacak
}
}
class IsletimSistemi
{
static void KullaniciTikladiginda()
{
buton1.Click;
}
}
Kuşkusuz bu program çalışmayacaktır. Yalnızca Windows formlarındaki olayların nasıl işlediğini anlamanız için bu örneği verdim. IsletimSistemi sınıfının arka planda sürekli çalıştığını düşünebilirsiniz. Şimdi artık olaylarla ilgili gerçek örneğimize başlayabiliriz:
using System;
using System.Windows.Forms;
class Form1:Form
{
private Button buton;
public Form1()
{
buton=new Button();
buton.Text="Tıkla";
this.Controls.Add(buton);
buton.Click+=new EventHandler(Tiklandiginda);
}
static void Main()
{
Application.Run(new Form1());
}
void Tiklandiginda(object o,EventArgs e)
{
MessageBox.Show("Butona tıkladınız");
}
}
EventArgs System alanında ve MessageBox System.Windows.Forms isim alanında birer sınıflardır. MessageBox sınıfının static Show() metodu ekrana bir ileti kutusunun gelmesini sağlar. EventArgs ise olayla ilgili ek bilgileri tutan sınıftır. Diğer form kontrollerini bir sonraki konumuz olan Visual Studio.NET dersinde göreceğiz. Yani diğer kontrolleri formumuza kodlarla değil, Visual Studio.NET ile getireceğiz.