ANKUZEF PROGRAMLAMA II DERSİ ÇALIŞMA DOKÜMANI 2023 OCAK
Hüseyin ŞİMŞEK – Bilgisayar Programcılığı Bölümü
Dikkat: İlk üç sayfada önemli kodların resimleri paylaşıldı. Ancak sayfa 4 ve sonrasında gerçekten sınav çalışmanızda fayda sağlayacak şekilde hocanın anlatımları birebir aynı sırayla bu dokümana anlatım ve resimlerle birlikte aktarıldı.
En önemli kod bloğu: (Nasıl ve hangi mantıkla oluşturulduğu ilerde açıklanıyor)

Bir fonksiyon oluşturma:


Satırın sonuna listele fonksiyonunu yazmazsak öğrenci ekle butonuna bastığımızda eklenen öğrenci listeye yansımaz, akabinde listele butonuna basmak gerekir. Öğrenci ekle butonunu tıkladığımızda listeye anında kişinin yansımasını istiyorsak, yukarıdaki komut bloğunun en altına listele() metodunu yazarak çağırmamız gerekir.


CellClick: Listede tıkladığımız satıra ait kişi bilgilerinin sol taraftaki textboxlarda görünür olmasını sağlar.

MESSAGE BOX LA KONTROL VE UYARI MESAJI YANSITMA
ŞİMDİ EN BAŞTAN FORMLARIN HAZIRLANMASINDA KULLANILAN KODLARI NASIL OLUŞTURUYORUZ?
FORMUN KENDİSİNİ TIKLADIĞIMIZDA ÇIKAN KOD BLOĞU:

HER ZAMAN ÖNCELİKLE CONNECTION STRING :

SONRA FORM LOAD A GELİP AÇ KAPA YAPIYORUZ:

SONRA DATA ADAPTER I YAZIYORUZ, İKİ PARAMETRE İSTİYOR BİRİ SQL DİĞERİ CONNECTIONIN İSMİ:

Böylelikle;

Şimdi data yı data table a yükle (Fill):

Şimdi datagridview dgvListe yi dolduralım:

BİTTİ
Bu arada, sql değişkeni oluşturarak en üst satıra sql sorguyu yazabiliriz böylede data adapter içine uzunca sorgu yazmadan sql yazabiliriz.

HADİ ŞİMDİ BUNU FONKSİYONA ÇEVİRELİM!
Bunun için
Öğrenci Ekle ve Ders Ekle komutları karşılaştırması (en alt satırlara dikkat, fonksiyon çağırıyoruz) :


Fonksiyonlar da burada:

Bu iki fonksiyonu birleştirelim: Dikkat edelim aralarındaki tek fark sql in sonundaki tbl_Ogrenci ve tbl_Dersler

Bundan sonra artık metodu çağırırken listele(); dersek hata verir çünkü parantez içine sql komutunu yazmamız gerekecek artık: Bunun için Form_Load satırına, btnListele_Click satırına ve btnOgrEkle_Click satırına buradaki metotların içine listele metodunu yerleştirirken, öğrenci verileri aktarılacağı için sql komutu olarak
listele(“SELECT *FROM tbl_Ogrenci”);
yazacağız.

Lakin, btnDersEkle_Click satırı fonksiyonunun içine yazacağım listele metodunun içine ise ders ekle ye ilişkin sql komutunu yazacağım (zira listele fonksiyonunu ortak yapmıştık tek fark sql sorgusunun sonundaki öğrenci ve derler tablosu parametreleriydi).

ŞİMDİ TABLODA İKİ TANE GRIDVIEW OLUŞTURDUK DİYELİM.
İkinci DGV ın ismi dgvYedek olsun:

Bu durumda hangi tabloyu hangi dgv a aktaracağız sorunu oluştu: Bunun için fonksiyonumuzu yeniden yazacağız. Parantez içine önce sql komutumuzu girdikten sonra ikinci parametre olarak dgvListe ya da dgvYedek i belirtmemiz gerekecek.
Önce fonksiyonumuzu bulalım: Kod sayfasının en üstünde InitializeComponent in altındaydı: (Tüm kod bloğuna dikkat connection string en üstte)

Şimdi sql i nereye yerleştireceğiz o parametreyi yazmalıyım: dgv imiş gibi davransın:

Ama dgvListe yi değiştirip artık dgv nin datasource unu kullan demeliyim: Böylece listele fonksiyonum artık çalışmayacak.

Şimdi sıra fonksiyonu nerede çağıracaksak oralara gitmeye geldi. İlgili yere gidip fonksiyonun içine sql sorgusunu yazdıktan sonra virgül atıp ikinci parametre olan dgv yi yazacağız. Ancak hangi dgv yi istiyorsak onu belirteceğiz:
Aşağıda Form_Load da 1. Dgv; Listele butonuna tıklayınca da ikinci gridview a listeyi yansıtmış olduk:

İstersek bir tablonun görünmemesini sağlayabiliriz: Visible özelliğini Properties den false yaparız. Sonra istersek kod tarafında düzeltebiliriz bunu:

Şimdi sıra filtrelemede:

Bunun için her harfi yazdığımızda sql sorgu yapacak bir kod olmalı: Properties de TextChanged özelliğini kullanarak yapıyoruz:

Text her değiştiğinde ne olsun? TextChanged i tıklayınca bu metod geliyor:

Şimdi bunun içine text her değiştiğinde ne olsun istiyorsak onu yazacağız: (SQL komutu demiştik) string sql:

Burada txtAra.Text= kullanıcı ne yazarsa demek, devamı da % olarak devam. Bunu da dgvliste de göstersin diye fonksiyon çağırdık en altta.
Fonksiyonuma input olarak ben string sql sorgumu girdiğimden filtre bu sorguyu yapıyor. Önce ilk girilen harfi alıp listeliyor sonra ikinci, üçüncü… % işaretiyle…
‘ ” +txtAra.Text “ ‘ = önce tek sonra çift tırnak sonra +txtAra.Text ……
ŞİMDİ SIRA RADIO BUTTONLARDA

Tıkladığımız yansısın istiyorsak, if komutu kullanmalıyız:
Radiobuttona tıklayınca açılan kod da if girip içine string sql yazıp: öğrenci checked ise tbl_Ogrenci ; Dersler checked ise tbl_Dersler yazacağız:

Bunu textChanged metodunun içinde her ikisini ayarlayarak da yapabiliriz:

Bu kod uzun oldu en üste ortak bir sql yazınca altta tekrarlı sql komutu yazılmış. { } içindeki ilk sql i silip yerine öğrenci checked değilse(notchecked) yani (!rbOgrenci.Checked) komutu yazabiliriz:

Şimdi de Öğrenci Ekleyi de fonksiyona döküyoruz:

Sonra da aşağılara gelip Öğrenci Ekle metodu içine ekle metodunu yazabiliriz. Sql sorgusu üst satırda mevcut dikkat)

BAŞKA BİR ÖRNEK
Bir fonksiyon yazalım: ogrenciEkle(45, “Ali”,”Kara”) yazayım bitsin dersek?
Ya da dersEkle (“Matematik”, 5).
Burada otomatik yazılanın gelmesini istersek
diyebiliriz.
TEKRAR ÖRNEKLER:

Fonksiyon oluşturuyoruz:

VIZE FINAL NOTU ORTALAMA

Fonksiyonunu yazalım: (fonksiyon bölümlerine yazacağız tabii ki)

Öncelikle double olacak, not çünkü ve ortalama alınıyor. Adını ortalama koyalım. İki değişken var, ikisi de text, yani string. Bunları double a çevirelim. O yüzden Convert.ToDuoble(vize) ve Convert.ToDuoble(final)diyoruz. Bu arada yapacağımız işlemin sonuç değişkeni var onu da işlemin başına yerleştirip üst satırda double olarak tanımlayalım. double sonuc = 0
Ve nihayet return sonuc;
Şimdi Kaydet butonunun kod bloğuna gidip oraya fonksiyonu yazıyoruz:


Şayet oluşturduğumuz vize ve final değişkenlerini başta double yapsaydık ki yapsak daha iyi olur?

O zaman da fonksiyonun içinde text leri double a convert ederdik:

Ortalama Hesaplamayı yaptık, şimdi SQL sorgusunu halledelim:

Tabii ki String olacak:


Şimdi programın kırılmaması için programda takılma olmasın diye try catch yapalım:
Mesela en üst satır sonunda ortlama yazılmış bu kodun kırılmasına neden olması lazım. Bu sıkıntıyı message boxla bize yakalayıp bildirmesini istiyorsak try catch yaparız: Bunun için de try catch in ortasında execution komutunu yazarız, zira onu yakalamasını istiyoruz neden execute olmadığını.

Komutu yerleştirdikten sonra catch e exeption yazdırıyoruz mesela adı ex olsun, ex i de message box ta yazdırıyoruz ex.Message formatında. MessageBox.Show un formatı bu (ama istersek bir metin yazıp “” içine alıp string ifade de yazdırabiliriz).

Sorunu düzelttikten sonra try-catch in altında connection ı close edip en altta fonksiyonumuzu yazabiliriz artık:

Şimdi de karşılığına bakalım:

Peşpeşe 5 işlemi yaptığımda notlar kısmına yansıdığını gördük.
Daha güzel nasıl yapabiliriz?
Tüm ID leri değil de -çünkü okuması zorlaşıyor belirsizlik var- sadece verisini girdiğimiz öğrencinin notları gelsin istiyorsak: WHERE i sql ifadede kullanarak yaparız.

Bu koda göre girdiğimiz öğrencinin ID nosu ve tüm ders notları tblNotlar’a yansır.
Başka bir işle: Örneğin ilk datagridview da öğrenci seçimi yaptığımda tblNotlar a bu öğrencinin verilerinin yansımasını istersem: Cell_Click özelliğini kullanırız. Bunun için öğrenci tablosunda Cell_Click kodunu yazdığımız bloğa gidip, yukarıda oluşturduğumuz listele fonksiyonumuzu oraya copy paste yapmalıyız.


Sonuç olarak tblNotlar tablosunda öğrenci adını ve soyadını göremiyoruz.
Burada öğrenci adını görmemiz gayet iyi olacaktır. Bunun için de INNERJOIN vs. kullanarak gerçekleştirebiliriz.
SON OLARAK KAYDET BUTONUNDAKİ İŞLEVLERİ GÖRELİM:

DERS 35:
Burada, üç adet datagridview dan birini silip combobox koyuyoruz.

dgvDersler silinince ona ait kodları siliyoruz.
comboBox ı tıklayınca açılan kod bloğuna: adını cbDersler olsun.
Listele fonksiyonumuzda ne yaptıysak, listele2 adlı yeni bir fonksiyon oluşturup içine aynı kodu yazabiliriz. Tek farkı, artık dersleri datagridviewe değil, ComboBox a taşıyacağız. Bu nedenle,


Bunu da kod üzerinde yapalım ve koda geri dönelim:

Şimdi, iki adet datagridview, bir combobox var, belki daha sonra listbox oluşturacağım veya story ye göre projeye başka bileşenler de konulacak. Her defasında yeni bir fonksiyon yazmaktansa bunları birleştirebilirim. Zira, şayet bu bileşenler veritabanımdaki bir listeden bilgi alıyorsa birleştirmem en mantıklısı. Dersler tablosundan veya öğrenci tablosundan… datatable.
Dolayısıyla şimdi mevcut iki fonksiyonu silip bunların yerine bana datatable türünden bir değişken döndüren bir fonksiyon yazabilirsem en mantıklı çözümü üretmiş olurum.
Bunun için listele2 yi silelim. Şimdi bir fonksiyon yazacağım ve bu fonksiyon bana datatable türünden bir değişken döndürecek. Bunu bir örnekten alıntılayarak üretelim. Mesela private double örneğim var vize ve final notları ortalamasını aldığım:

Şimdi bunun üzerinden gidelim.










Ekle dediğimizde adı frmDersler olan boş bir form açılacak: Bu pencere nasıl açılacak? Önce kodu yazacağım sonra da Dersler menüsüne tıkladığımda açılacak.

Desrleri çift tıklayınca açılan kod bloğu:

Şimdi bu süslü parantez aralığına kod yazacağız. Varolan yani oluşturulmuş bir formu nasıl buraya import ederiz?

Şimdi açılı pencere varken Dersleri tıkladığımızda formDersler açılacak ancak üstüste yanyana gelecekler. Bu durum bir karışıklığa mahal verebilir. Bu yüzden açılan pencerelerde bir hiyerarşi oluşturup son açılan kapanmadan diğeri açılmasın şeklinde düzenleme yapabiliriz. Bunun için dialog kullanacağız.
Artık formDersler kapanmadan ana form görülemez. Kapattığımızda da dispose olsun istiyoruz daha düzgün kullanılması için. Kontrolün forma geçmesi geçmemesi, işlemin yer işgal etmesi vs e karşı. Makinayı uğraştırmamak için işlemi kapatmak amacıyla dispose. (dispose=bellekten sil)

Şimdi yeni formu düzenleyelim: Bunun için Connection oluşturup, Form_Load u açıp Fonksiyonlarımı yazabilirim hatta bunları bir önceki kodlardan copy pazte yapabilirim. Ancak bu kodun sadeliğini engeller ve mükerrerlikler hoş olmaz. Bu nedenle, class yapısını kullanmamız en mantıklısı.
Yine Çözüm Gezgini penceresinde projemizi sağ tıklayıp Ekle + Sınıf ı tıklayacağız:
Açılan pencerede formun adını fonksiyonlar.cs yazıyoruz. Zira fonksiyonlarımın tümünü bir yerde toplamak istiyorum.
Şimdi Çözüm Gezgininde projemin altında bu fonksiyonlar.cs görünecek: Tıkladığımızda solda kod penceresi açılacak ve tüm fonksiyonlarımı buraya yazabileceğim.

Şimdi iç sayfalarda bulunan bütün önemli fonksiyonları buraya alacağız:

Şimdi de yeni formumuza gelelim. Oluşturduğumuz fonksiyonlara atıflar yapacağız şimdi. Yeni forma bir adet boş bir dgv yükledik. Bu dgv ye listemizi atayacağız. Öyleyse veriAl mantıklı. Öyleyse
Bu arada, birden çok fonksiyonum mevcut ama listele yi private oluşturduğumdan açılan hızlı pencerelerde sadece veriAl görünüyor. O yüzden listele yi de public yapalım.

Problem çözüldü artık listele fonksiyonumuz gelecek: Yeni formun kod sayfasına yazıyoruz. Dikkat: veriAl da sadece sql ifade istenirken, listele de sql ve neyin işleneceği (dgv) vardı.

Şimdi geri alıyoruz zira bize derslerin görünmesi yetiyor. Malum formun menü adı derslerdi.

Bundan sonra artık menü ye hangi bileşeni eklediysem onunla ilgili olarak yukarıdaki işlemin aynısını yapacağım. Örneğin;
Öğrenci menü sünü tıklayıp boş bir form açacağım. Bunun için Projemi sağ tıklayıp, Ekle + Windows Forms , formun adını oluştur, formu aç dgv penceresi yerleştir, dgv ye isim ver-dgvOgrenciler, Ana forma geri dönüp menu de Öğrenciyi çift tıkla kod sayfası açılsın, Sonra formu türetelim: (Şu an veritabanıyla bir işimiz yok formu oluşturalım şimdi dolayısıyla bağlantıya- connection burada gerek yok. veritabanı olayı sonra gelecek):

Bu sayfa menulerin windows formunu oluşturduğumuz kod sayfası. Yukarıdaki kod dersler menüsünündü. Aşağıya aynısını öğrenci için yaptık. Şimdi veritabanı class mevzularına gelelim:
Öğrenci için oluşturduğumuz yeni formu açıp tıklayıp Form_Load u açalım.

Benzer şekilde Menu den Notlar ı da yapıyoruz.
ÖNEMLİ: Foksiyonlardan nesne türetip o nesnenin özelliklerine erişebiliyoruz:
fonksiyonlar fn= new fonksiyonlar();

Şimdi Notları yeni formda açtık ancak ID bilgileri var sadece, öğrencinin adı soyadı ve dersin adını da görmem gerekir. Burada INNERJOIN devreye girecek.

Bunun için öncelikle SQL Management Studio yu açıyoruz ve tables ın altında view da sağ click yapıp new view ı açıyoruz:

Bu sayfa açılıyor:

Üç tabloyu da seçtiğimizde karşımıza bağlantılarıyla geliyorlar:

Bu bağlantıların çizgilerini remove ediyoruz. Kendimiz oluşturacağımız tablonun içereceği verileri tıklayarak bir kod oluşturacağız.


Adını vwNotlar99 koyduk. Şimdi yeni formumuzda sql ifadedeki tblNotlar ın yerine vwNotlar99 ı koyacağız.

Şimdi Notları tıkladığımızda karşımıza gelen liste:

View daki kodları alıp yerleştirmemize gerek yok, view ın kendisini yerleştirmemiz yeterli.
ŞİMDİ DE RENKLENDİRME:

Kod bloğunda, ortalama adlı bir değişken oluşturuyoruz. Zira bunu if yapısına alıp 50 den küçük 80 den büyük vs. diyeceğiz. Bunu da cells’in 5. Si ortalama idi (final=4; vize=3). Bu yüzden Cells[5] yapıyoruz. Sonra da if yapısını oluşturuyoruz:

Çalıştırdığımızda Ela’nın ortalamalarından iki notu 80 nin üstündeyken bir notu 50 nin altında olduğunu görebiliyoruz.(dikkat edilirse başka bir view dan çekilmiş.)

ÖNEMLİ: Bir nesnenin fonksiyonuna method denir.(ÖRNEK: fn.veriAl )