7 Kasım 2009 Cumartesi

C# - Windows Application ; KacanButton

C# - Windows Application ; KacanButton


Tekrar merhaba. Bu uygulamamızda çeşitli nesnelerin özelliklerini, if yapısını, eğlenceli olduğunu düşündüğüm
bir uygulamada öğreneceğiz.

Hemen yeni bir Windows Form Application açıyorum, ismine 'blogKacanButton' diyorum.
Şimdi ilk olarak formumuzun border özelliğine bakalım. Bunun için; Form u seçip F4 ile onun özelliklerine gidiyoruz. Buradan FormBorderStyle (Font içinde) özelliğini "none" yapıp gözlemliyoruz. Evet gördüğünüz gibi üstteki title ve kapatma, küçültme düğmeleri kayboldu. Form'un özelliklerinde Layout kısmında StartPosition ise; Bize Form'un açıldığında nerede açılmasını istediğimizi verir. Bunada "CenterScreen" diyorum.

Ok. Uygulamamızın başlığı olarak bir Label düşünüyorum. Hemen Toolbox'tan yeni bir Label alıp ekliyorum. Label özelliklerinde AutoSize'ını "false" ve Dock özelliğini "top" ayarlıyorum. Dock özelliği, o nesnenin formun neresinde olacağını belirler. Normalde biz Label'ı çekip genişletip, yerini kendimizde verebilirdik. Dock bize bu kolaylığı sağlıyor.
Label'ımızın dock'unu top yaptıktan sonra rengi ve fontuyla oynayıp güzel bir başlık haline getiriyorum.

Form'unda BackColor özelliğini "Gray" yapıyorum. Button eklemek kaldı, hemen bir Button ekliyorum.
Button'un özelliklerinden; Text'ini "Tıkla",FlatStyle'ını "Flat" ve BackColor'ını Turuncu, FlatAppearance sekmesinden BorderSize'ını "2" olarak ayarlıyorum.



Design tamamdır. Burası kolay zaten.Şimdi geldik en zevkli kısma.
Kodlar:
Şimdi biraz düşünelim. Kod yazmaya nereden başlamalı, ihtiyaçlar neler? Karışımıza çıkacak problemler neler olabilir? Biz uygulama açılınca Button'un sürekli hareket halinde olmasını ve tıklanmasının zor olmasını istiyoruz öyle değilmi? Ozaman kod'u Form'un Load eventine yazarız ki form açıldığında çalışmaya başlasın. Fakat ozaman da sadece form açıldığında çalışır ve tekrarlanmaz öyle değilmi? Nereye yazmalı? Bizim tekrarlanan nesnemiz neydi, Timer. Ok ozaman Timer'ın "Tick" eventine yazmamız gerekir. Böylece her 1sn'de bir Timer tick olacak ve içindeki kodları çalıştıracak. Yani Button'un yerini değiştirecektir. Hemen bir Timer ekleyip enable'ını True yapıyorumki form açılır açılmaz başlasın saymaya. Interval'i de 1000 olsun (1sn). Timer'a çift tıklayıp kod tarafına geçiyorum.

Temel olarak bir nesnenin yerini nasıl değiştiririz sorusu var. Bir nesnenin Left ve Top özelliklerini değiştirerek yerini değiştirebiliriz. Bizimde bu uygulamada yapacağımız şey bu. Ama bu Left ve Top değerinin sürekli değişmesi gerekiyor öyle değilmi? O zaman Random nesnesini kullanacağız. Random'dan kendimize Left ve Top değerleri alıp bunu Button'umuza vereceğiz. Peki bu Button'un Left ve Top özelliğinin değişme sıklığı nasıl olacak? Yani düşünün bir kere değişip öylece kaldığını? Hiç işimize yaramaz öyle değilmi. Örnek mesela her 1sn'de bir yer değiştirse? Peki böyle tekrarlanan şeyler için ne kullanıyorduk? Daha öncede söylediğimiz gibi cevap "Timer". Evet yavaştan kafamızda oluşmaya başladı nasıl birşey olacağı. Buda bir programcı için iyi birşeydir. Önce zihninde oluşturur daha sonra dener ve karşılaştığın problemleri gidermeye çalışırsın.

Timer'ın enable'ını true yapıyorumki form açılır açılmaz başlasın saymaya. Interval'i de 1000 olsun (1sn)

Random nesnemi üretiyorum. 

    Random rnd = new Random();

Şimdi kordinatları üretme zamanı. Form'un genişliği 300px olduğunu düşünün. Ben eğer Button'un Left ine (yani soldan olan uzaklığına) 300 verirsem Button nerede olur? Dışarıda kalır öyle değilmi? Çünkü Button'unda bir genişliği var. Oda soldan başlar. Genişliğinin 15px olduğunu varsayarsak, benim maksimum Left' i 300 - 15 vermem gerekirki Button görünebilsin. Yani Button'un sağ köşesine göre hesap yapmam lazım.
Tamamdır Left parametremizi x, top parametremizi de y diye int bir değişkene atıyorum.

int x = rnd.Next(this.Width - button1.Width);
int y = rnd.Next(this.Height - (label1.Height + button1.Height));

ve Random nesnesi ile rastgele ürettiğim aralıkları Button'umuzun left ve top'ına veriyorum:

button1.Left = x;
button1.Top = y;

Dipnot: Uygulamanın kapatma tuşunu iptal ettiyseniz. Yani FormBorderStyle'ı "none" seçtiyseniz; Uygulamayı kapatmak için VS2008'e gelip üstteki sekmelerden Stop button'una basmanız yeterlidir.

Çalıştırıp gözlemliyorum. Hmm Label'ın içine giriyor Button öyle değilmi? Bir problem var. Demek ki "y" parametrem doğru çalışmıyor.
Biraz düşünelim şimdi. "y" neden üst'e girdi? Hmm ok başlangıç olarak "0" değerini alıyorda ondan. Random'un Next() metodunun 2 "Overload"u (2 farklı şekilde yazım yöntemi) vardır.
İlki; Next(sayi) girersiniz ve size 0 dan sayi'ya kadar rastgele rakamlar üretir.
İkinci yöntem ise; Başlangıç sayısı verebilirsiniz Ör) Next(0,10) bu ise size 0 ile 10 arası değerler getirir.

Dipnot: 0 dahildir ama 10 dahil değildir. yani 0 <= x < 10 gibi düşünebilirsiniz.

Ozaman hemen y parametremi modifiye ediyorum. Başlangıç değeri Label1'in yüksekliği (height) kadar ayarlıyorum.

int y = rnd.Next(label1.Height, this.Height - (label1.Height + button1.Height));

Çalıştırıp gözlemliyorum. Güzel fakat nasıl kapatılacak bu uygulama? Şöyle olsun mu: iki olasılık olsun,
1 - ESC tuşuna basıldığında uygulama kapansın
2 - Button'a tıklandığında mesaj versin ve uygulama kapansın.

- 2'yi hemen yapalım; Button'a çift tıklayıp kapatan kodu yazıyorum:

private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Tebrikler! Kazandın");
            this.Close();//button'a tıklarsa kapatsın
        }

- 1'e gelelim. Şimdi ESC tuşunu bilgisayara tanıtmamız lazım. Yani algılaması gerekir. Bunun için form'un özelliklerine F4 ile gidiyoruz. Oradan yukarıda sarı bir şimşek işareti var. Bu "Event" anlamına gelir. Ona basıp eventlerine geçiyoruz form'un. Key sekmesinde "KeyDown", "KeyPress", "KeyUp" gibi eventler var gördüğünüz gibi.

KeyUp : Bir tuşa basıp çektiğiniz anca çalışan eventtir.
KeyDown : ESC, Enter, Delete, Insert gibi tuşları algılamada kullanılan eventtir.
KeyPress : Buda "a,b" gibi klavye tuşlarını algılamada kullanılır.

Biz KeyDown'ı kullanacağız. Bunun için KeyDown'a çift tıklayarak kod tarafına geçiyoruz.



private void Form1_KeyDown(object sender, KeyEventArgs e)

Şimdi gördüğünüz gibi biz genellikle "EventArgs e" yi görürdük eventlerde öyle değilmi. Buradaki "KeyEventArgs e"; "e." yaparak yeni özellikleri, parametreleri kullanabilirsin demektir. Yani eğer eventte "EventArgs e" den farklı birşey yazıyorsa, her zaman "e." yaparak onun özelliklerini kullanabiliriz.

Bizde aynen "e." yaparak bakıyoruz özelliklerine. Gördüğünüz gibi bir sürü özellik geldi. Biz burda KeyCode'u kullanacağız. Gelelim kod'u yazmaya. Şimdi ne dedik? 'ESC'ye basınca' dedik öyle değilmi? Bu bir koşul cümlesi dikkatinizi çekerim. Koşulları kontrol ettirmek için çoğu program dilinde "if" yapısı kullanılır.

if de parantez içi Boolean tiptir. Yani geriye ya True yada False döndürür. Ör) if(sayi == 2) Bu örnekte sayi'nın 2 olup olmadığı kontrol ediliyor. Eğer sayı 2 ise True değil ise False geri dönüyor.

Dipnot : C#'ta bir eşitlik kontrol ettirmek isteniyorsa; Çift eşit (==) kullanılır.

Kendi örneğimize gelirsek.

if (e.KeyCode == Keys.Escape)
            {
                this.Close();
            }

Çalıştırıp gözlemleyelim. Çalışmıyor, sebebi herhangi bir key'i algılatmak istediğinizde, eğer form'un özelliklerinden "KeyPreview"i True yapmazsanız, bu kodların hiç birini algılatamazsınız. Ozaman True yapalım değilmi.

Tamamdır hallettik. Yalnız bir detay var, ki programcılık detay işidir. Space'e basınca Button'a basılmış olarak algılıyor ve kapatıyor. Bunu engellemek için bir if daha lazım. Hemen ekleyelim. Hatta MessageBox'ta mesaj yazalım Space'e basılınca:

else if (e.KeyCode == Keys.Space)
            {
                MessageBox.Show("Yemezler müdür!");
            }

Bir MessageBox'ta üstteki ne ekliyim daha güzel olsun. Çalıştırıp gözlemliyorum. Hmm bu biraz kolay olmuş değilmi? :) Zorlaştıralım. Timer'ın interval'ini 200 yaptım.

Güzel oldu gibi. Şimdilik benden bu kadar, tekrar görüşmek üzere.


KODLAR:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace blogKacanButton
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Random rnd = new Random();//nesnemi ürettim
            int x = rnd.Next(this.Width - button1.Width);//genişlik değerimi ürettim
            int y = rnd.Next(label1.Height, this.Height - (label1.Height + button1.Height));//yükseklik değerimi ürettim
            button1.Left = x;//genişliği button'a atadım
            button1.Top = y;//yüksekliği button'a atadım
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Tebrikler! Kazandın");
            this.Close();//button'a tıklarsa kapatsın
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)//ESC e basılmış ise
            {
                MessageBox.Show("Görüşürüz Müdür");
                this.Close();//formu kapat
            }
            else if (e.KeyCode == Keys.Space)
            {
                MessageBox.Show("Yemezler müdür!");
            }
        }
    }
}

Link : KacanButton

Hiç yorum yok:

Yorum Gönder