Dinamik buton oluşturup kontrol etme

Runtime zamanında bazen dinamik buton oluşturmak istemişizdir. Yada kod ile buton oluşturmak…  Buna, kullanıcının ihtiyacına karşı olarak projelerimizde kullanmaktayız.

dinamik-coklu-buton

Örneği anlamak için form ekranıına bir adet label, textbox ve buton resimdeki gibi oluşturup kodlamaya geçebiliriz. Kullanıcıdan alınan buton sayısı doğrultusunda form ekranın büyüklüğüne göre oluşturulan butonları boyutlandıra biliriz.

Boyutlandırmadaki amaç birden fazla buton eklendiği için normal şartlarda yan yana veya alt alta standart boyutta buton oluşturmakta. Hem bunları bir sıraya sokup hemde formun genişliğine ve yüksekliğini referans alarak butonları düzgün bir şekilde göstere biliriz.

 private void button1_Click(object sender, EventArgs e)
        {
            int butonSayisi = Convert.ToInt32(textBox1.Text);
            int sol = 1; //formun sol tarafından atanan değer
            int alt = 50; // formun üst tarafından atanan değer
            int bol; // bolme işlemindeki amaç formun boyutuna göre butonları sıralı bir şekilde görebilmek için
            bol = Convert.ToInt32(Math.Ceiling(Math.Sqrt(butonSayisi)));

            for (int i = 1; i <= butonSayisi; i++)  // girilen buton sayısına göre döngü şartı sağlanana kadar oluşturmakta
            {
                Button btn = new Button();
                btn.Name = i.ToString();

                btn.AutoSize = false;

                btn.Size = new Size(this.Width / bol, this.Height / (bol * 2));
                btn.Text = "Buton " + i.ToString();
                btn.Font = new Font(btn.Font.FontFamily.Name, 18);
                btn.Location = new Point(sol, alt);
                this.Controls.Add(btn);
                sol += btn.Width + 5;

                if (sol + this.Width / bol > this.Width) // bunu yapmasaydık butonlar yan yana dizilir alt satıra geçmedi
                {
                    sol = 1;
                    alt += this.Height / (bol * 2) + 5;
                }

                btn.Click += new EventHandler(dinamikMetod); // dinamik olarak oluşturulan butonu kontrol etmek için her oluşturulan butonun clik olayına atıyoruz.

            }
        }

Kod içinde yeterli açıklama mevcut.  Genel olarak anlatırsak; form içinde butonları düzgün bir şekilde görünebilmesi için girilen buton sayısı değerinin Math.Sqrt ile kare kökünü alıp sonucun doğru bir şekilde çıkması için Math.Ceiling ile yuvarladık.  Bunu yapmamızın nedeni, kullanıcının girdiği buton sayısına göre butonların büyüklüğünü ayarlayabilmek. Bunu yapmasak kullanıcı 100 tane buton istese, buton büyüklüğünü önceden girdiğimiz için butonları çoğu taşacak veya üst üste gelerek kötü bir görüntü elde edeceğiz. Örneği uygulayarak konuyu anlayacağınızı umuyorum.

Dinamik olarak oluşturulan butonu nasıl yakalayabiliriz derseniz üst tarafta oluşturduğumuz butonlar içine atanan clik olayını metod yardımı ile yakalayıp, runtime da oluşturulan butona tıklanıldığında o butona ait isim, vs özelliklerine ulaşabiliriz. Bunun için alttaki kodları örneğimize dahil ederek konuyu öğrenebilirsiniz.

 protected void dinamikMetod(object sender, EventArgs e)
        {
            Button dinamikButon = (sender as Button);
            MessageBox.Show(dinamikButon.Text + " isimli butona tıkladınız");
        }

Burada tıklatılan butonun textini mesaj kutusunda gösterdik.

Aynı şekilde diğer kontrolleri de(label, combobox gibi) oluşturabiliriz.  Bu örnek uygulamayı nerede kullanabiliriz derseniz; adisyon programında işletme sahibinden girilen masa sayısını form ekranına gösterip, herhangi masa hesabını açmak ve kapatmak için kullanabiliriz.

Listview içinde toplama işlemi

Listview’i çok severiz vesselam. Hele ki veri giriş-çıkış, gösterme işlemlerinde vazgeçilmezlerimiz arasındadır. Görüntüde listview sadece basit bir kontrol gibi gözükür. Ama birçok işimizi listview yardımı ile hallede bilmekteyiz. Bu kontrolü daha fazla sakız yapmadan başlıkta belirttiğim meseleye gelelim.

Mevzumuz şu; herhangi bir yerden listviewe girilen aynı isimdeki değerleri farklı satıra yazdırmadan mevcut satır üzerine yazdırmak. Örnekle açıklayacak olursak, stok takip programında listview üzerinden stoklarını tuttuğumuz ürünler için, aynı üründen eklediğimizde o ürünün sadece miktarını, adetini veya fiyatının üzerine ekleyerek yazdırmak. Bir nevi aynı isimdeki şeylerin rakamsal değerlerini toplayarak tek satırda birleştirmek.

Senaryo veya örnek aklınızda biraz canlandı ise ufak bir örnek ile pekiştirebiliriz. Resimde görüldüğü gibi 2 textbox bir buton ve birde baş rolümüz olan listview kontrolünü forma sürükleyin. Textbox’un biri eklenenin adı, diğerinde ise eklenenin miktarı girişi yapılmakta. Kendi kendinize ben hazırım diyorsanız butona çift tıklayıp kodlamaya geçe biliriz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
private void button1_Click(object sender, EventArgs e)
        {
            string adi = txtadi.Text;
            int miktar = int.Parse(txtmiktar.Text);


            bool varmi=false;

            foreach (ListViewItem item in listView1.Items)
            {
                if (item.Text == adi)
                {
                    varmi = true;
                }
            }

            if (varmi)
            {
                foreach (ListViewItem i in listView1.Items)
                {
                    if (i.Text == adi)
                    {
                        int icindeki = int.Parse(i.SubItems[1].Text);
                        icindeki += miktar;
                        i.SubItems[1].Text = Convert.ToString(icindeki);
                    }
                }
            }
            else
            {
                ListViewItem lv = new ListViewItem();
                lv.Text = adi.ToString();
                lv.SubItems.Add(miktar.ToString());
                listView1.Items.Add(lv);
            }

        }

Görüldüğü üzere ilk olarak textbox ları doğru bir şekilde değişkenlere atadık. Ardından programın kilit kodu olan bool tipli değişkeni false olarak tanımladık. Bunu yaptıktan sonra foreach ile girilmek istenenin adını listView1 kontrolünün içinde arattık. Eğer içinde varsa önceden false olarak tanımladığımız varmi değişkenine true değerini atadık.

Akabinde bu atanan true değeri ile if-else kullanarak tekrar listView1 içinde aynı isimdeki girdinin miktarı üzerine girilen miktarı topladık. Eğer daha önce aynı isimde girdi girilmemiş ise listView1’e yeni satır isim ve miktarı ile ekledik…

Form içinde alt form açmak

Bazen birden fazla form ile çalışmak isteye biliriz. Böyle durumlarda düz mantıkla projemizde çalışacağımız kadar form oluştururuz. Bunu birkaç form ile halledebiliriz. Ancak iş kullanıcının istediği doğrultusunda açılması gerek form olduğunda yapışıp kalabiliriz. Bunu önlemek için yardımımıza MDI formlar koşuyor.

MDI form mantığını Excel için örnek verebiliriz. Biliyorsunuz ki Excel içinde birden fazla excel dosyası açıp çalışabilmek deyiz. Adobe Photoshop programını da örnek göstere biliriz. İki ayrı resim ile çalışıldığında Photoshop içinde iki ayrı çalışma sayfası açılır onları istediğimiz yere Photoshop içinde hareket ettirebiliyoruz.

Örnekleri ve hikayeyi fazla uzatmadan MDI, form içinde form açma uygulamasına geçelim. Öncelikle bir tane ana form oluşturalım. Bunun için formun IsMdiContainer özelliğini True olarak ayarlayın.(Resimdeki gibi form arkaplan gri renkte olacak)

Form içinde alt form açmak için anaforma bir adet menü oluşturmamız gerekecek. Toolbox daki MenuStrip kontrolünü sürükleyip bırakarak oluşturabiliriz. Menü otomatik en üste çıkacak, özellikler bölümünden konumunu ayarlaya bilirsiniz. Üzerine tıklayarak menü isimlerini basit bir şekilde oluşturun.

Örneğe uygun olarak resimdeki gibi oluşturabilirsiniz. Ardından açılacak olan alt form için yeni windows form ekleyin. Formun IsMdiContainer özelliğini False olarak bırakıp, Name özelliğini altform olarak yazarsanız örneğimizdeki kodları daha iyi anlayabilirsiniz.

Çalışır vaziyetteki örneğimiz

Bunları yaptıktan sonra kod kısmına geçebiliriz. İlk önce yeni alt form oluşturmak için Yeni Form Aç menümüze çift tıklayıp Click olayına alttaki kodları yazalım.

1
2
3
4
5
6
7
8
9
10
11
12
int formsayim = 1;  // formsayim değişkenini global olarak tanımlayın !

 int formno= formsayim++;

            altform cocuk = new altform();

            cocuk.Name = "cocukform" + formno.ToString();
            cocuk.Text= "Yeni Alt Form " + formno.ToString();

            cocuk.MdiParent = this;

            cocuk.Show();

Açılan her yeni form için form numarasını 1 arttırarak yeni çocuk formun name özelliğine atadık. Sırası ile kapat menüsüne çift tıklayıp Clik olayına alttaki kodları yazalım

1
2
3
4
5
 if (this.ActiveMdiChild != null)
            {
                Form frm = ActiveMdiChild;
                frm.Close();
            }

Buradaki kod açılı form varsa en onu kapatır. Son olarak hepsini kapat menüsüne de çift tıklayıp Clik olayına alttaki kodları yazalım.

1
2
3
4
foreach (Form frm in this.MdiChildren)
            {
                frm.Close();
            }

foreach döngüsü ile form içindeki tüm çocuk formları kapatır.

C# da TC kimlik no algoritma ile doğrulama

Başlığı daha sade anlaşılır tutmak isterdim ama saat gecenin 02:36’sı kusura bakmayın. Hikaye blogu değil burası dediğinizi, daha şimdiden sinirlendiğinizi hissedebiliyorum. Küçük büyük bir çok projede TC kimlik numarsı doğrulama gibi sıkıntımız olmuştur. Bilindiği gibi TC kimlik numarası rastgele sayılardan oluşmaz, belirli algoritma sonucunda oluşmuştur. Bunun hakkında fazla konuşmadan isteyenler için burada ki adreste algoritma hakkında detaylı bilgiye ulaşabilir.

Algoritmalardan hariç webservis ile de internet üzerinden TC kimlik no doğrulanmakta. (Webservisi kullanmak için bu “https://tckimlik.nvi.gov.tr/Service/KPSPublic.asmx” adresi kullanabilirsiniz) Ama biz webservis fazla kurcalamadan internetsiz organik yöntemler ile hızlı bir şekilde doğrulamayı planlıyoruz.

C# ile basit form üzerinde textbox, label, buton kullanarak anlama babında yaptığımız uygulama ile yazımıza devam edelim. TC kimlik numaramızın ilk 10 rakamın toplamının birler basamağı, 11. rakamı vermekte. Bu şekilde TC kimli no kontrolü yapılabilmekte. Bu algoritma ile yola çıkarak programımızı geliştirdik. Form için gerekli elemanları ekledikten sonra kod kısmına geçerek daha iyi anlayabiliriz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
        private void button1_Click(object sender, EventArgs e)
        {

            if (11 != textBox1.Text.Length)  // Girilen sayı 11 haneli olmak zorunda
            {
                label1.Text = "Eksik veya fazla sayı girildi";
            }

            else
            {
                int toplam = 0; // 1. Açıklama
               
                for (int i = 0; i < textBox1.Text.Length - 1; i++) // 2. Açıklama
                {
                    toplam += Convert.ToInt32(textBox1.Text[i].ToString()); // 3. Açıklama
                }
               
                if (toplam.ToString()[1] == textBox1.Text[10]) // 4. Açıklama  
                {
                    label1.Text = "Tc kimlik Numarası Doğru";  // 5. Açıklama
                }
                else
                {
                    label1.Text = "Tc kimlik Numarası Yanlış";
                }

            }


        }

Buton click olayı ile başlayan programımızın açıklamasını kodların yorum kısmından alttaki açıklamalarla öğrenebilirsiniz;

  1. Uygulamanın kopma noktası bu değişken. 0 değeri vererek tanımlıyoruz. Bu şekilde yapılmasını amacı değişkenin for blogu içinde kullanıması için.
  2. Girilen Tc kimlik numarasının ilk 10 rakamını almak için length dan 1 eksiğini döndürdük
  3. Girilen sayıları soldan sağa doğru tek tek topladık, sonucu toplam değişkeninde biriktirdik.
  4. Burada toplam sayının birler basamağını almak için 1 yazdık 0 ile onlar basamağındaki sayıyı alırdık. Alınan sayı ile girilen tc kimlik numarasının 10. indeksi yani (0 dan başladığını hatırlayalım) 11. sayı ile karşılaştırdık.
  5. Eşit ise TC kimlik numarası doğru…

Kısa yoldan toplu textbox temizleme

Bu konu hakkında birçok yazı yazılmıştır. Daha önce yazılanları unutun demeyeceğim, yedekte kalması babında kaynaklanarak yazdığım en kısa toplu textbox temizleme metodu şimdilik bu olsa gerek;

Projelerimizde ki formlarda birden çok textbox kullanmışızdır. Malum işlem yapıldıktan sonra kendiliğinden temizlemediği için iş yazılımcıya düşmekte. Foreach ile yapacağımız bu işlemi resimdeki gibi form tasarlayıp buton yardımı ile gerçekleştirebilirsiniz.

1
2
3
4
5
6
7
8
9
10
 private void button1_Click(object sender, EventArgs e)
        {
            foreach (Control ktn in this.Controls)
            {
                if (ktn is TextBox)
                {
                   ktn.Text="";
                }
            }
        }

Form içindeki tüm textboxları temizleme ihtiyacı duymaya bilirsiniz. Mesela belirli textboxları temizlemek için form a panel ekleyip toplu temizlemek istediğiniz textboxları panel içine koyabilirsiniz. Bunun için yapmamız gereken this(form içindeki tüm kontrolleri kontrol etmek için kullanırız) yerine panel1 şeklinde kontrol etmek;

1
2
3
4
5
6
7
  foreach (Control ktn in panel1.Controls)
            {
                if (ktn is TextBox)
                {
                   ktn.Text="";
                }
            }

Stored procedure output ile mail kontrolü

Veritabanımızda sık sık sp’leri kullanırız. Bir çok işlemi sp üzerinde yapabilmekteyiz. Örnek verecek olursak; ürün giriş veya üye kayıt kısmında; masaüstü veya web sitemiz dolayısı ile parametre gönderip işlemi Stored procedure ile bitiriyoruz.

Sp’deki output ile veri tabanından parametre alabiliyoruz. Şöyle ki; e-posta adreslerini tutan veritabanımız ve C# da yazılmış masaüstü uygulamamız olsun. Form yardımı ile girilen e-posta adresini veritabanından kontrol edip, mail adresi varsa kullanıcıya kayıtlı olduğunu belirtip, yoksa kayıt ettirebiliriz. Benzer şekilde Stored procedure output ile arama yaptırabiliriz. Burada yapılan olay parametrenin databasee gidip tekrar geri dönmesinden ibarettir.

Başlıkta belirttiğim üzere mail kontrolü yapan Stored procedure‘li masaüstü uygulaması yapalım;

Resimdeki gibi form ekranı oluşturduktan sonra kod kısmına geçmeden veritabanımıza output parametreli Stored procedure yazalım;

1
2
3
4
5
6
7
8
9
10
11
12
CREATE proc sp_coder_output (@dmail nvarchar(50), @var INT output)
AS
BEGIN
IF EXISTS (SELECT mail FROM tblmail WHERE mail=@dmail)
BEGIN
SELECT @var=1
END
ELSE
BEGIN
INSERT INTO tblmail (mail) VALUES (@dmail)
END
END

Burada @dmail ve output parametreli tabloda olmayan @var isimli int tipli değişken tanımladık. İf ile kontrol edip, eğer mail adresi daha önceden eklenmiş ise @var değişkenine 1 atamakta, yoksa kayıt etmekte (Database adı: coder, tablo adı: tblmail, kolon adı: mail, tabloda id ve mail kolonları bulunmakta). Sql ile işimi bitirip formda kaldığımız yerden devam edelim.

Butonu çift tıklayıp kod tarafına geliyoruz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
string varmi;
            SqlConnection sql = new SqlConnection("server=.; database=coder; trusted_connection=true;");
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = sql;

            cmd.CommandText = "sp_coder_output";
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add("@dmail", SqlDbType.NVarChar, 50);
            cmd.Parameters.Add("@var", SqlDbType.Int);
           
            cmd.Parameters["@dmail"].Value = textBox1.Text;
            cmd.Parameters["@var"].Direction = ParameterDirection.Output;

            sql.Open();
            cmd.ExecuteNonQuery();
            varmi = cmd.Parameters["@var"].Value.ToString();

            if (varmi == "1")
            {
                MessageBox.Show("Daha önce eklenmiş mail adresi...");
            }
            else
            {
                MessageBox.Show("Mail adresi kayıt edildi...");
            }
sql.Close();

SqlConnection yardımı ile veri tabanına bağlandık. SqlCommand ile Procedure’ü çalıştırdık. Değişkenleri kolonlar ve tiplerine uygun olarak ekledik. ParameterDirection.Output ile parametrenin geri gelmesini sağlıyoruz. Burada gelen parametreyi Label1’e yazdırıyoruz. Değeri 1 olursa daha önceden eklenmiştir mesajı alınacak, eğer label1’in değeri 1 olmaz ise kayıt edip, edildi mesajı verecek.

Javascript if ile gün saati uygulaması

JavaScript : Netscape Navigator 2.0 ile birlikte Brendan Eich tarafından geliştirilen ve önceleri Mocha daha sonra LiveScript olarak adlandırılan ve en sonunda şu anki adını alan JavaScript dili başlangıçta sadece istemci taraflı (client-side) yorumlanan bir betik programlama dilidir.(Kaynak :http://tr.wikipedia.org/wiki/JavaScript)

Javascript de sık kullanılan if yapısı ile gün içi uygulamamızı yapalım. Uygulamamızda; linke tıkladığımızda gün içindeki zamana göre selam vermesi istersek;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 <script language="javascript" type="text/javascript">
function ifuygulama() {
            var tarih = new Date();
            var saat = tarih.getHours();

            if (Saat >= 6 && Saat < 12) {
                alert("Günaydın");
            }
            else if (Saat >= 12 && Saat < 14) {
                alert("Tünaydın");
            }
            else if (Saat >= 14 && Saat < 18) {
                alert("İyi Günler");
            }
            else if (Saat >= 18 && Saat < 22) {
                alert("İyi Akşamlar");
            }
            else {
                alert("İyi Geceler");
            }
        }
 </script>

<body>
<a href="javascript:ifuygulama()">Selam ver</a><br />
 </body>

Buradaki işlem; yeni tarih tanımlayıp istenilen zaman değerlerine şart koyarak alert ile mesaj verdirmek.