C# Windows Forms ile basit bir hesap makinesi yapmak için forma iki TextBox, işlem Button'ları ve sonucu gösterecek bir Label koyarsın. Butonun Click olayında kutulardaki metinleri sayıya çevirir, seçilen işlemi uygular ve sonucu etikete yazarsın. Konsol uygulaması yazdıysan elindeki bilgi yeterli: değişkenler, if ve aritmetik işlemler aynen geçerli. Yeni olan tek şey, kodun ne zaman çalışacağını kullanıcının tıklaması belirler.
Bu yazıda önce yalnızca toplama yapan küçük bir sürüm kurup çalıştıracak, sonra dört işleme ve hatalı girişlerin yakalanmasına geçeceksin.
Hesap makinesi projesi hangi beş adıma bölünür?
Proje beş küçük adıma ayrılır. Her adımı ayrı düşünmek hata çıktığında sorunun nerede olduğunu bulmayı kolaylaştırır:
- Tasarım: Kontrolleri forma yerleştirir ve adlandırırsın.
- Veri alma:
TextBoxiçindeki metni okursun. - Doğrulama: Boş girişi, geçersiz sayıyı ve sıfıra bölmeyi kontrol edersin.
- Hesaplama: Seçilen işlemi iki sayıya uygularsın.
- Çıktı gösterme: Sonucu ya da hata mesajını
Label'a yazarsın.
Başlamak için Visual Studio'da yeni proje oluştururken Windows Forms uygulaması şablonunu seç ve dil olarak C#'ı işaretle. Windows Forms, Windows işletim sistemi için masaüstü arayüz geliştirmeye yarayan bir teknolojidir. Şablon listesinde göremiyorsan masaüstü uygulaması geliştirmeye yönelik bileşenlerin kurulu olup olmadığını Visual Studio Installer'dan kontrol edebilirsin. Proje açılınca ekranda boş bir form görürsün; bu, tasarım adımının başlangıç noktasıdır.
Formu nasıl tasarlarsın ve kontrollere nasıl ad verirsin?

Araç Kutusu'ndan forma iki TextBox, bir Label ve işlem Button'ları sürükle. Yerleşim, renk ve yazı tipi bu aşamada önemsiz; kontroller birbirine karışmayacak kadar düzgün dursun yeter. Asıl iş, her kontrolü seçip Özellikler penceresindeki Name alanına anlamlı bir ad vermektir.
Bu yazıda şu adları kullanacağız: ilk kutu txtSayi1, ikinci kutu txtSayi2, toplama düğmesi btnTopla, sonuç etiketi lblSonuc. Dört işleme geçince diğer düğmeler btnCikar, btnCarp ve btnBol olacak. Başlangıçta metin kutuları textBox1, textBox2 gibi adlar alır. Formda birkaç kutu olunca hangisinin ilk sayı olduğunu hatırlamak zorlaşır, kodu bir gün sonra açtığında da çözmen uzun sürer.
Önek kuralı basittir: txt metin kutusu, btn düğme, lbl etiket demektir. Önekten sonra kontrolün görevini yaz. Fark kodu okurken belli olur. button1_Click içindeki label3.Text = ... satırı hangi düğmeden ve hangi etiketten söz ettiğini söylemez. btnTopla_Click içindeki lblSonuc.Text = ... satırını ise formu hiç görmeden bile anlarsın.
Önce yalnızca toplama yapan çalışır örnek nasıl yazılır?
Tasarım ekranında btnTopla'ya çift tıkla. Visual Studio kod dosyasında boş bir olay metodu oluşturur ve düğmeyi bu metoda bağlar. Bağlantı kodu, formun Designer dosyasında otomatik yazılır. Metodun içini şöyle doldur:
private void btnTopla_Click(object sender, EventArgs e)
{
decimal sayi1 = decimal.Parse(txtSayi1.Text);
decimal sayi2 = decimal.Parse(txtSayi2.Text);
decimal toplam = sayi1 + sayi2;
lblSonuc.Text = "Sonuç: " + toplam;
}
Programı çalıştır, ilk kutuya 12, ikinci kutuya 8 yaz ve düğmeye tıkla. Etiket şunu gösterir:
Sonuç: 20
Kod beş adımın dördünü karşılıyor: kutulardan veri okur, hesaplar ve çıktıyı gösterir. Doğrulama adımı henüz eksik.
Windows Forms projesinde butonun Click olayı, kullanıcı eylemi ile program mantığı arasındaki bağlantıyı kurar. Konsolda Console.ReadLine() satırına gelen program durur ve sen yazana kadar bekler; akışı kod belirler. Windows Forms'ta form açık kalır ve program beklemede durur. Kullanıcı düğmeye bastığında ilgili metot çalışır. Yani akışı kullanıcının eylemleri yönlendirir, metodlar ise bu eylemlere verilen yanıtlardır.
Bu sürümün zayıf noktası decimal.Parse'tır. Kutular boşsa ya da içine harf yazılmışsa program hata verip kapanır. Sonraki bölümde bunu decimal.TryParse ile güvenli hâle getireceğiz.
decimal.TryParse neden gerekir, virgül ve nokta farkı ne yaratır?
TextBox'taki değer her zaman metindir. decimal.Parse ile çevirirsen kullanıcı "abc" yazdığında program hata verip kapanır. decimal.TryParse ise çevirmeyi dener ve bool döndürür: başarılıysa true, değilse false. Sayı, out parametresiyle alınır. Program çökmez, sen de kullanıcıya mesaj gösterebilirsin.
if (!decimal.TryParse(txtSayi1.Text, out decimal sayi1))
{
MessageBox.Show("Birinci sayı geçerli değil. Ondalık için virgül kullan.");
return;
}
lblSonuc.Text = "Okunan sayı: " + sayi1;
Giriş değerlerine göre davranış şöyledir:
3,5girilirse sayı kabul edilir ve etikette "Okunan sayı: 3,5" görünür.abcgirilirse uyarı kutusu açılır,returnile metottan çıkılır ve etiket değişmez.- Alan boşsa
TryParseyinefalsedöndürür.
Ondalık ayracı bilgisayarın kültür ayarına bağlıdır. TryParse, ayrı bir ayar vermezsen o anki kültürü kullanır. Türkçe (tr-TR) kültürde ondalık ayracı virgüldür, nokta ise binlik ayracı olarak yorumlanır. Bu yüzden 3,5 beklediğin gibi okunurken 3.5 aynı değeri vermeyebilir. Kullanıcıya "ondalık için virgül kullan" mesajı vermek bu karışıklığı önler. CultureInfo.InvariantCulture ile sabit kültür kullanmak da mümkündür, ama bu projede varsayılan kültürle devam ediyoruz.
Dört işleme nasıl genişletirsin, boş giriş ve sıfıra bölmeyi nasıl yakalarsın?

Her butonda aynı doğrulamayı tekrar yazmak yerine üç adım izle. Önce iki sayıyı okuyup kontrol eden ortak bir yardımcı metot yaz. Sonra btnTopla, btnCikar, btnCarp ve btnBol Click olaylarında bu metodu çağır. Son olarak bölmede ikinci sayı sıfırsa işlemi durdur. Boş girişi string.IsNullOrWhiteSpace yakalar; yalnızca boşluk içeren metinleri de boş sayar.
private bool SayilariAl(out decimal a, out decimal b)
{
a = 0;
b = 0;
if (string.IsNullOrWhiteSpace(txtSayi1.Text) || string.IsNullOrWhiteSpace(txtSayi2.Text))
{
MessageBox.Show("İki sayıyı da gir.");
return false;
}
if (!decimal.TryParse(txtSayi1.Text, out a) || !decimal.TryParse(txtSayi2.Text, out b))
{
MessageBox.Show("Geçerli bir sayı gir. Ondalık için virgül kullan.");
return false;
}
return true;
}
private void btnTopla_Click(object sender, EventArgs e)
{
if (!SayilariAl(out decimal a, out decimal b)) return;
lblSonuc.Text = (a + b).ToString();
}
private void btnCikar_Click(object sender, EventArgs e)
{
if (!SayilariAl(out decimal a, out decimal b)) return;
lblSonuc.Text = (a - b).ToString();
}
private void btnCarp_Click(object sender, EventArgs e)
{
if (!SayilariAl(out decimal a, out decimal b)) return;
lblSonuc.Text = (a * b).ToString();
}
private void btnBol_Click(object sender, EventArgs e)
{
if (!SayilariAl(out decimal a, out decimal b)) return;
if (b == 0)
{
MessageBox.Show("Sıfıra bölme yapılamaz.");
return;
}
lblSonuc.Text = (a / b).ToString();
}
İlk sayıya 10, ikinci sayıya 4 yazarsan beklenen sonuçlar şöyledir: Topla için 14, Çıkar için 6, Çarp için 40, Böl için 2,5. İkinci sayı 0 olduğunda Böl "Sıfıra bölme yapılamaz." uyarısını gösterir ve etiket değişmez. Alanlardan biri boşsa "İki sayıyı da gir." mesajı çıkar.
Program çalışmıyorsa hangi noktaları kontrol etmelisin?
Hata mesajı vermeden sessiz kalan ya da yanlış sonuç gösteren bir hesap makinesinde şu listeyi sırayla gözden geçir:
- Click olayı butona bağlı mı? Butonu seçip Özellikler penceresindeki Olaylar sekmesinde
Clicksatırında metot adının yazılı olduğunu kontrol et. - Kontrol adları kodla uyuşuyor mu? Tasarımda
txtSayi1olan bir kutuya koddatxtSayi_1demek derleme hatası verir. - Ondalık sayıyı virgülle mi girdin? Nokta, tr-TR kültüründe beklediğin değeri vermeyebilir.
- Alanlardan biri boş mu kaldı?
- Bölmede ikinci sayıyı 0 mı yazdın?
- Değişkenleri
intolarak mı tanımladın?intondalık tutmaz; 10 bölü 4 işleminde 2,5 yerine 2 görürsün. Bu projededecimalkullanılır.
Hatayı bulmakta zorlanıyorsan sorun çoğu zaman olay bağlantısında ya da temel kavramlardadır. C# söz dizimi ve temel kavramlardaki seviyeni görmek için ücretsiz C# bilgi testini çözebilirsin. Bu test yalnızca seviye ölçümüdür; hangi konulara tekrar bakman gerektiğini gösterir.
Projeyi büyütmeden önce hangi düşünme becerisini ölçmelisin?
Hesap makinesinin asıl zorluğu arayüz değildir. Kontrolleri forma sürüklemek dakikalar sürer. Zor olan, girdinin geçerli olup olmadığına karar vermek, sıfıra bölme gibi sınır durumlarını öngörmek ve işlemleri doğru sırayla uygulamaktır. Bu beceri hangi arayüz teknolojisini kullanırsan kullan aynı kalır.
Sonraki küçük geliştirmeler bu mantığı sınar:
- Temizle butonu: iki kutuyu ve sonuç etiketini başlangıç durumuna döndürür.
- Mod alma:
%işleciyle yeni bir buton ekler. Bölmedeki sıfır kontrolü burada da gerekir. - İşlem geçmişi: her hesaplamayı
ListBoxkontrolüne "8 / 2 = 4" biçiminde ekler.
Zincirleme işlem yazmaya başladığında (örneğin 2 + 3 * 4) işlem önceliği sorunuyla karşılaşırsın. Bu noktada kod yazmadan önce adımları kâğıda dökmek işini kolaylaştırır. Mantığını dilden bağımsız ölçmek istersen ücretsiz Algoritmik Düşünme Testi bu konuda başlangıç noktası olabilir.
Sık Sorulan Sorular
Windows Forms hesap makinesinde sayıları neden decimal ile tutmalıyım?
decimal ondalık sayıları onluk tabanda tuttuğu için 0,1 + 0,2 gibi işlemler beklediğin 0,3 sonucunu verir. double ikilik tabanda çalışır ve aynı toplama 0,30000000000000004 gibi küçük sapmalar üretebilir. Gündelik hesap makinesinde kullanıcı tam sonuç görmek ister, bu yüzden decimal daha güvenli bir seçimdir.
TextBox'a nokta ile ondalık sayı yazınca neden hata alıyorum?
Türkçe kültür ayarında ondalık ayracı virgüldür. decimal.TryParse varsayılan olarak bilgisayarın kültürünü kullanır, bu yüzden "2.5" yazıldığında ya false döner ya da nokta binlik ayracı sayılıp sayı beklenmedik biçimde okunur. Kullanıcıdan virgül yazmasını isteyebilir ya da CultureInfo.InvariantCulture vererek noktalı girişi kabul edebilirsin.
Her işlem için ayrı buton yerine tek buton ve ComboBox kullanılabilir mi?
Evet. ComboBox içine +, -, *, / seçeneklerini koyar, "Hesapla" butonunun Click olayında seçilen değeri switch ile işlersin. Seçim yapılmadan butona basılırsa kullanıcıya bir uyarı göstermen gerekir. Bu yapı, yeni işlem eklemeyi tek bir case satırına indirir.
Windows Forms projesi Mac ya da Linux'ta çalışır mı?
Windows Forms, Windows'a özgü bir arayüz teknolojisidir; Mac ve Linux'ta doğrudan çalışmaz. Aynı hesap makinesi mantığını konsol uygulaması olarak veya çok platformlu bir arayüz çerçevesiyle yazabilirsin. Mac kullanıyorsan Windows kurulu bir sanal makine de seçenek olabilir.
Hesap makinesi küçük bir proje gibi görünse de girdi alma, doğrulama, karar verme ve sonucu gösterme zincirini baştan sona yaşatır. Bu zinciri kendi başına kurabildiğinde, aynı yapıyı bir sonraki masaüstü uygulamanda da kullanırsın.