Makale Özeti

Makalemiz boyunca oop prensiplerine sadık kalarak bir ürün uygulaması geliştiriceğiz . Uygulamamız içerisinde kullanıcağımız alanlarımızı kendi tarafımızda nesne olarak tasarlayıp o sekilde kullanıcağız . Uygulamanın ilerleyen aşamalarında Binary olarak serileştirme ve okuma işlemlerinede Sql içerisinde Group By deyimlerine ve bir çok önemli noktalara kısaca bakıcağız.

Makale

Nesneler ile çalışmak . (OOP Kuralları Çerçevesinde )

Yapacağımız uygulamamızda AdventureWorks database i içerisindeki Production.ProductSubCategory ve Production.Product tablolarını kullanarak ürünlerimizin kategorilerini ve bu kategoriler içerisindeki ürün miktarlarını Kategori listbox ımız içerisinde listeleyeceğiz ve kategoriler içerisindeki bir kategori adına tıkladığımız zaman ürünler kısmında o kategoriye ait ürünlerimizi listeleyeceğiz .

Yine ilgili ürünümüzün adına tıkladığımız zaman seçtiğimiz ürünümüzün bilgilerini alıp bu urunu alış veriş sepetimize ekleyeceğiz . Ürünleri satın al Link label ımıza tıkladığımız zaman seçtiğimiz ürünümüzü sepetimize eklemiş olacağız. Sepetimizi bu şekilde doldurduğumuz ve artık alış veriş imizi bitirmek istediğimiz zaman sepetim link label tıklayıp sepetimizin içeriğini ve toplam ödeyeceğimiz miktarımızı görüceğiz.

Sepetimizdeki ürünlerimizi o an satın almak istemiyor isek Sepetimi kaydet tıklayıp bunları arka alanda binary olarak serileştiricegiz. Uygulamamızı kapatıp tekrar açtığımız zaman yazmış olduğumuz uygulama ilgili yere bakacak ve eğer ilgili yerde sepetimize ait bir binary bilgi var ise uygulamamız form load aşamasında iken bize eski sepetimizde olan ürünlerimizin miktarını gösterecek ve bunu sepetimize ekleyip eklemeyeceğimizi soracaktır.

Evet seçeneğini seçer isek ürünlerimiz o anki sepetimize dahil olacak ve alış veriş yapmaya devam edeceğiz.

Yukarıda uygulama içerisindeki iş akışını anlattıktan sonra şimdi kodlarımızı yazarak neyi nasıl ve nerde niçin kullandığımızı detaylı olarak inceleyelim ve üzerinde konusalım .

İlk olarak ürün kategorilerimizi ve o kategoriye ait kaç adet ürünümüzün bulunduğunu Kategori listemize almak için gerekli olacak metodumuzu Dal.cs adını verdiğimiz class ımız içerisine yazalım .

Dal.cs : Dal.cs class ımız bizim database ile ilgili olan işlemlerimizin yürütüldüğü kısım olacaktır. Uygulamamız boyunca dal .cs adını verdiğimiz bu class ımız sayesinde sadece database olaylarını burada işlemiş olacağız .

Şimdi database imize ( AdventureWorks) bağlanıp bilgilerimiz olan Kategori ve Urunlerimizi çekelim.

SqlConnection con { get; set; }
SqlCommand cmd { get; set; }

public Dal()
{
con = new SqlConnection("data source=.;initial catalog=AdventureWorks;integrated security=true;MultipleActiveResultSets=true");

}

public SqlDataReader AnaKategoriGetir()
{

cmd = new SqlCommand(@"select p.ProductSubCategoryId,pps.Name,count(p.Name) from Production.ProductSubCategory pps join Production.Product p on pps.ProductSubCategoryId=p.ProductSubCategoryId group by pps.Name,p.ProductSubCategoryId", con);

ConnectionIslemleri();

return cmd.ExecuteReader();

} public

SqlDataReader UrunGetir(int id)

{

cmd = new SqlCommand("select ProductId,Name,Color,convert(decimal,ListPrice),SafetyStockLevel from Production.Product where ProductSubCategoryId=@Id",con);
cmd.Parameters.Add("@Id", System.Data.SqlDbType.Int).Value = id; return cmd.ExecuteReader();

}

public void ConnectionIslemleri()
{
if (con.State == System.Data.ConnectionState.Closed)
con.Open();
else
con.Close();
}

Şimdi kodlarımızı açıklayalım ve kategori ve ürün bilgilerimizi nasıl aldığımızı inceleyelim .

İlk önce Sqlconnection ve SqlCommand adında iki adet pointerımızı namespace düzeyinde oluşturduk dal class ımız her örneklendiği zaman database bağlantı string imi zinde oluşmasını sağlamak için dal class ımızın yapıcı metoduna

Con = new Sqlconnection (“data source = .; initial catalog = AdventureWorks; integrated security = true; MultipleActiveResultSets = true;”);

Şeklinde burada con nesnemizi örnekledik. Bağlantı satırımızda database e ulaşır iken yani bağlantımızı açar iken MARS desteğin inde açık olarak kullanacağımızı belirttik .

Mars destegi default olarak açık bir şekilde gelmemektedir. Eğer bir uygulama içerisinde eş zamanlı olarak birden fazla SqlDataReader tanımı kullanacak isek bizim Mars desteğine ihtiyacımız vardır.

Mars desteğimizi aktif olarak kullanmak için MultipleActiveResultSets = true; şeklinde açmamız yeterli olacaktır.

Simdi dal class ımız içerisinde kategorilerimizi ve ürünlerimizi bir üst katmana yani yonetim katmanımıza ulaştıralım .

AnaKategoriGetir metodumuz metot imzasında parametre almaz ve geriye SqlDatareader nesnesi dondurur .

Metodumuzun içerisinde SqlCommand hazırlanış aşamasında sql bağlanıp iki tablo arasında Group by ile gruplama yapıyoruz .
Tsql komutumuzun yapısını inceleyelim…

select p.ProductSubCategoryId,pps.Name,count(p.Name) from Production.ProductSubCategory pps join Production.Product p
on pps.ProductSubCategoryId=p.ProductSubCategoryId group by pps.Name,p.ProductSubCategoryId

Production.ProductSubCategory ( pps ) tablomuz ile Production.Product tablolarının icindeki ProductSubCategoryId field ları eşit olan verilerimizi adına ve categoryid sine göre gruplandırıp sorgumuzu hazırladık .

ProductionProductSubCategory artık pps diyelim. Ve Productin.Product p diyelim . tablolarımızın icerisinde ise p.ProductSubCategoryID , pps.Name , count(p.Name) olarak alanlarımızı çektik .

Hangi kategori deki urunden kaç adet oldugunu bize gosteren kısım elbetteki count(p.name) olan kısımdır .

Sqlcommand imizi bu sekilde hazırladık dan sonra ConnectionIslemleri adını verdigimiz metotumuz icerisinden baglantımızı actık bu hazırlamıs oldugumuz metotumuz eger baglantı kapalı ise acar acık ise baglantımızı kapatır . Çok işe yarıyan bu metotumuz sayesinde biz dal.cs içerisindeki bu metotu public olarak erisim belirleyicisini acar isek baska class lar uzerinde iken bile baglantımızı açabilir veya kapatabiliriz.

Baglantımızı actıkdan sonra return anahtar soz dizimi ile cmd.ExecuteReader() metotu sayesinde bir ust katmana SqlDataReader olarak verimizi ilettik .

Simdi aynı işlemin benzerini UrunGetir Metotumuz icin yapalım . UrunGetir metotumuzun metot imzasında int tipinden bir parametre ve geridonus deger SqlDataReader seklindedir .

Command ımızı inceleyelim . sqlcommand kısmında yukarıdan parametre olarak gelen ( yani kategori id olarak gelen ) urunleri bulmak isteyecegiz.

select ProductId,Name,Color,convert(decimal,ListPrice),SafetyStockLevel from Production.Product where ProductSubCategoryId=@Id

Bunun icin yukarıda belirttiğimiz sql komutumuz da Production.Product tablosunda bulunan ProductId,Name,Color,Listprice,SafetyStoctLevel alanlarımızı Production.Product tablomuzda ProductionSubCategory alanına dısarıdan gelen degerimizi olan id nin esit oldugu kayıtları bulup getiriyoruz .

Gelen degerimizi bir ust katmana yani yonetim katmanına kategori metotumuzdaki gibi sql data reader seklinde geri veriyoruz .

Dal .cs class ımız içerisinde database ile olan tum işlemlerimizi bitirdik . Artık database kısmı ile bir işlemimiz olursa dal.cs icine yazıcagız ve buradan erisim saglayıp bir ust katmana gondericegiz .

Gonderdigimiz bu verileri simdi Yonetim katmanı olarak ele aldıgımız Helper.cs adını verdigimiz sınıf icerisinde erisip bilgilerimizi işleyelim .

Helper sınıfımız Dal.cs sınıfından gelen verileri işleyip son katman olan form katmanına ulaştıran kısımdır . Helper aynı zamanda bizim ufak işlerimizide yapabilir .

Simdi Helper class ımız orneklendigi zaman dal uzerindeki metotlara helper nesnemizin erismesi icin helper ın yapıcı metotunda dal nesnemizi ornekleyelim ve işlemlerimize başlayalım .

class Helper
{
Dal d;
public Helper()
{
d = new Dal();
}

Yukarıdada oldugu gibii Helper nesnemiz örneklendigi zaman dal nesnemizide iceride yani helper nesnemizin yapıcı metotunda ornekledik artık helper üzerinden dal nesnemizin tum public metotlarına erisebilir ve kullana biliriz .

Şimdi dal sınıfımızdan gelen urunlerimiz helper katmanında işleyecegimizi söylemiştik peki dal kısmından bana geri donen sqldatareader nesnelerimi ben birer tip uzerine almam gerekmektedir . bu yuzden simdi helper nesnemizi bu sekilde bırakıp 2 adet tip tanımlayalım .

Alt Kategori ve Urun adında iki adet tip tanımlayalım ki helper nesnemiz uzerinde daldan gelen verilerimizi bu tiplerimizi kullanarak depolayalım .

Urun.cs

[Serializable]
public class Urun
{
public int UrunId { get; set; }
public string UrunAdi { get; set; }
public string Renk { get; set; }
public decimal Fiyat { get; set; }
public int StokMiktari { get; set; }

Yukarıdali kısımda fieldlarımızın tanımlamalarını yaptık .

public decimal StokTutari
{
get { return Fiyat * StokMiktari; }
}

StokTutari property kullanarak ufak bir hesaplama işlemi yaptırdık ki ilerde sepet hesaplama kısmında işimize oldukça yarayacaktır . Property miz sadece get edilebilir yani sadece veri gonderiri icerisine veri almaz …


public Urun(int urunid, string urunadi, string renk, decimal fiyat, int stokmiktari)
{
this.UrunId = urunid;
this.UrunAdi = urunadi;
this.Renk = renk;
this.Fiyat = fiyat;
this.StokMiktari = stokmiktari;
}
Yapıcı metotu kullanarak parametre olarak gelen verilerimizi tipimizi icerisinde olusturdugumuz degerlerimizin uzerine aldık .

public override string ToString()
{
return UrunAdi;
}

Önemli Soru : Neden override string ToString() olarak tipimizin tostring metotunu ezdik .

Cevabını makalemizin ilerleyen kısımlarında birebir uygulayıp cevaplayalım

Yukarıda olusturdugumuz Urun tipimizin icerisinde

UrunId – UrunAdı – Renk – Fiyat – Stokmiktarı – StokTutari adında fieldlarımız vardır .

Tipimizin erişim belirleyicisi public olup name space düzeyinde [Serializable] olarak işaretlenmiştir .

Simdi AltKategori tipimizi oluşturalim ve inceleyelim .

class AltKategori
{
public int KategoriId { get; set; }
public string KategoriAdi { get; set; }
public int UrunMiktari { get; set; }
public List<Urun> urunler { get; set; }

Yukarda tipimizde kullanıcagımız degiskenlerimizi olusturduk yalnız burda suna dikkat cekmek istyorum urunler degiskenimizin tipi List<Urun> olarak verilmistir yani tipimiz icerisinde bir list generic atadık bize ayrı ayrı SqlDataReader olarak gelen verilerimizi artık bir tipde MARS destegini kullanarak işleyeceğiz .

public AltKategori()
{
urunler = new List<Urun>();
}
public AltKategori(int kategoriid, string kategoriadi, int urunmiktari, List<Urun> uruns):this()
{

this.KategoriId = kategoriid;
this.KategoriAdi = kategoriadi;
this.UrunMiktari = urunmiktari;
this.urunler = uruns;
}
public override string ToString()
{
return string.Format("{0}({1})", KategoriAdi, UrunMiktari);
}

Kullanıcagımız tiplerimizi oluşturdukdan sonra artık helper sınıfımıza gidip dal sınıfımızdan gelen verilerimizi işleyip tiplerimiz uzerine alalım .

Helper.cs devam...

List<Urun> UrunTamamla(int id)

Urun tamamla metodumuz metot imzası olarak bizden int tipinden id değeri istemektedir ve geri dönüş değeri List<Urun> seklindedir.

{
List<Urun> urunler = new List<Urun>();
Urunler adında bir list<Urun> koleksiyonu oluşturdukdan sonra dal sınıfımızdan gelen bilgilerimizi artık list<urun> koleksiyonumuza dolduralım .

SqlDataReader dr = d.UrunGetir(id);
while (dr.Read()) dr.Read olana kadar bu işlemi gerçekleştir .
{
urunler.Add(new Urun(dr.GetInt32(0), dr.GetString(1),
dr.IsDBNull(2) ? "Renksiz" : dr.GetString(2), dr.GetDecimal(3), dr.GetInt16(4)));

While dongumuz içerisinde urunler adını verdigimiz koleksiyonumuzun .add metotu ile koleksiyonumuza gelen urunlerimizi doldurmaktayız . doldurma aşamasında eger database tarafından null olarak donen degerler var ise bunlara kod kısmında default degerler verip o sekilde koleksiyona atanmasını saglarız .
Bu işlemi yapan anahtar kelimemiz dr.IsDBNull dır . Database den gelen verinin null olması durumunda devreye girer ve belirledigimiz sekilde koleksiyona eklenmesini sağlar .
}
dr.Close(); Tüm okuma işlemimiz tamamlandıkdan sonra dr.close() metotunu kullanarak datareader ımızı kapatırız ve .
return urunler; list<urun> koleksiyonumuzu geri donus parametresi olarak veririz .
}

Yukarıda urunler metotumuzu yazdık ve c# komutlarımızın aralarına girerek açıklamaya çalıştık . Simdi kategorilerimizi çekelim .


public List<AltKategori> AltKategoriTamamla()
AltKategoriTamamla metotumuz metot imzasında herhangi bir parametre almamaktadır geri dönüş degeri ise List<AltKategori> olarak list generic koleksiyon geri döndürmektedir .
{
List<AltKategori> altKategoriler = new List<AltKategori>();
altKategoriler adında list<AltKategori> koleksiyonu oluşturdukdan sonra işlemlerimize başlayalım .
SqlDataReader dr = d.AnaKategoriGetir(); Dal tarafından gelen SqlDataReader yakalamak icin bu kısımda olusturdugumuz dr adındaki tipimiz ile verilerimizi dr nin üzerine aldık ve
while (dr.Read()) dr.Read () olana kadar while dongumuzun dönmesini sagladık .
{
altKategoriler.Add(new AltKategori(dr.GetInt32(0), dr.GetString(1), dr.GetInt32(2), UrunTamamla(dr.GetInt32(0))));
While döngümüz içerisinde altKategoriler koleksiyonumuzum add() metotunu kullanarak dr üzerindeki verilerimizi koleksiyonumuza verdik .

Yalnız AltKategori tipimiz en son olarak bizden list<urun> tipinden urun istemektedir . ve biz burada database tarafından gelen bir urun list generic koleksiyon bulamamakdayız . Ilk olarak tamınladıgımız metotumuz olan UrunTamamla metotumuzun geri dönüş parametresi List<Urun> olarak ayarladık ve deger olarak int tipinden id almakda idi .

Bu aşamada biz AltKategoriler adındaki list koleksiyonumuza uruntamamla metotumuzu verir ve id olarakda dr.GetInt32(0) kullanarak o Kategorinin id sini veririz.

Bu sekilde MARS destegini artık tam anlamı ile kullanmıs oluruz. Aynı anda iki adet SqlDataReader gider bilgileri alır ve AltKategoriTamamla metotumuz kendi icerisinde UrunTamamla metotunu cagırır ve istedigi List<Urun> parametresini alır .

}
dr.Close(); İşlemlerimiz bittikden sonra dr.Close() metotumuzu kullanarak SqlDataReader kapatırız .

d.ConnectionIslemleri(); Dal tarafında açık bıraktıgımız database baglantımızı artık kapatmamız gerekmektedir . Bunun icin Dal tarafında özellikle tanımladıgımız ConnectionIslemleri adını verdigimiz metotumuzu çağırıp otomatik olarak database baglantımızı kapatırız .

return altKategoriler;
ve son olarakda aldıgımız verilerimizi artık form katmanına taşırız.
}

Yukarıdaki işlemden sonra artık Form Tarafına gecip Dal tarafından aldıgımız Helper kısmında işledigimiz verilerimizi Form katmanında goruntuleyelim .

Yalnız form katmanından helper nesnemizin metotlarına ulaşmak için form um yapıcı metotunda Helper nesnemizi örneklememiz gerekmektedir .

public partial class Form1 : Form
{

Helper h;
AlinanUrunListesi a;
public Form1()
{
InitializeComponent();
h = new Helper();

Yukarıdaki şekilde Helper nesnemizi ornekledikden sonra …


Şimdi form tarafındaki listbox ımıza gidip verilerimizi baglayalım ve sonucunu gorelim .

Form load kısmında kategorilerimizi doldurmamız gerekmektedir. Bunun icin Form un Load kısmına gidelim ve

private void Form1_Load(object sender, EventArgs e)
{
lstKategoriler.DataSource = h.AltKategoriTamamla();

şeklinde listbox ımızın DataSource h.AltKategoriTamamla(); şeklinde belirtip uygulamamızı çalıştıralım .

Yukarıdada goruldügü gibi uygulamamız çalışmıştır Dal tarafından bilgilerimiz gelmiş Helper katmanında işlenmiş ve form katmanına ulaşmıştır

: Makale İcerisinde Sordugumuz Sorumuzun Cevabı :
Kategoriler listbox icindeki veriler Namespace.tipadı seklindedir. Bunun Tek nedeni TOSTRING METOTUNUN EZILMEMESIDIR .

Peki Neden bu şekilde davrandı uygulama : Uygulama içerisinde oluşturdugumuz tipimiz olan AltKategori tipimizin toString() metotunu override etmedigimiz zaman c# tostring() metotunun default tanımlanmıs degerlerini karsımıza cıkartır bunlarda Namespace ve tip adı şeklindedir.

Simdi AltKategori tipimize girip toString() metotumuzu override edelim .

public override string ToString()
{
return string.Format("{0}({1})", KategoriAdi, UrunMiktari);
}

Uygulamamızı Simdi Çalıştıralım .

Artık Kategorilerimiz listbox ımız içerisinde Urun adı ve o urune ait toplam sayımızı almış olduk .

Makalemiz içerisindeki sorumuzuda cevaplamış olduk . Simdi kategoriler kısmından bir kategoriye tıkladıgımız zaman urun listbox dolmasını sağlayalım .

Bunun için lstKategoriler_SelectedIndexChanged event kullanıcağız .

private void lstKategoriler_SelectedIndexChanged(object sender, EventArgs e)
{
lstUrunler.DataSource = ((AltKategori)lstKategoriler.SelectedItem).urunler;
}

lstKategoriler adını verdigimiz listbox ımızın selectedIndexChange event(olay) kullanarak lstUrunler listbox ımızın lstUrunler.Datasource secilen lstKategoriler ( AltKategori ) cast edip bunun uzerinde olan urunler field ımızı veririz. Urunler degerimiz list<urun> tipinde koleksiyon oldugu icin secilen kategorinin id sini alan ve o id e ait urunleri getiren list koleksiyon dur ve urunlerimiz bu sekilde dolmaktadır .

Şimdi uygulamamızı tekrar çalıştıralım ve bir kategori secelim urunler listbox ımızın dolmasını sağlayalım .

Uygulamamızı çalıştırıp kategorilerden Shorts (7) tıkladıgımız zaman 7 adet urunumuzun urunler kısmında belirdigini gördük burda şuna dikkatinizi çekmek isterim .

Urunler dolar iken asla ve asla gidip database tarafından almadık bilgilerimizi olusturdugumuz AltKategori tipimiz icindeki urunler kısmında aldık . Database e bir kere baglandık ve artık tum işlemlerimizi list koleksiyonumuz içerisinde yapmakdayız .

Son olarak sectigimiz ürünümüzün ürün bilgilerinin gelmesini saglayalım bunun icin form katmanında ufak bir metot yazalım .

public void YerlerineYerlestir(Urun u)
{
txtUrunId.Text = u.UrunId.ToString();
txtRenk.Text = u.Renk;
txtStokMiktar.Text = u.StokMiktari.ToString();
txtStokTutar.Text = u.StokTutari.ToString();
txtFiyat.Text = u.Fiyat.ToString();
}

YerlerineYerleştir metotumuz metot imzası olarak Urun tipinden parametre kabul etmektedir ve geri donus degeri void ( yoktur ) olarak belirlenmiştir .

Metot icerisinde form üzerindeki ilgili textboxlarımıza degerlerimiz atanmıştır .

Urunler listbox ımız üzerinden SelectedIndexChanged event ına gidip asagıdaki gibi bilgileri parametre olarak artık metotumuza verelim .

private void lstUrunler_SelectedIndexChanged(object sender, EventArgs e)
{
YerlerineYerlestir((Urun)lstUrunler.SelectedItem);
}

Metot icerisinde YerlerineYerleştir metotumuzu çagırdık metotumuz bizden urun tipinden parametre istemektedir bizde lsturunler.SelectedItem (Urun) cast ettik ve bu sekilde parametre olarak alınmasını sagladık . Urunler kısmında dolan veri list<Urun> tipinden oldugu icin cast sırasında herhangi bir degisiklik bir uyumsuzluk bulunmamaktadır .

Simdi uygulamamızı calıstıralım ve Kategori secelim Urun secelim ve urun bilgisini textboxlarımıza alalım .

Uygulamamız artık normal bir sekilde calısmaktadır . Artık urunumuz uzerindeki sepetleme işlemlerine baslayalım ve secitigimiz urunleri almaya baslayalım Alışverişimiz yapalım .

Sepetimizi hazırlamak icin ayrı bir sınıf olusturalim ve adına AlinanUrunListesi olark belirleyelim .

AlinanUrunListesi sınıfımız aldıgımız urunleri icerde bir koleksiyon ile tutucaktır .

class AlinanUrunListesi
{
static public List<Urun> alinanUrunListesi;
static public int UrunSayisi
{
get { return alinanUrunListesi.Count; } int urunsayısı property kullanrak icerde alinanUrunListesi.count; sayesinde koleksiyonumuzdaki degerlerin sayısını aldık ve get ettik .
}
static AlinanUrunListesi()
{
alinanUrunListesi = new List<Urun>(); Orneklendigi sırada bellege bir kere cıkması icin yapıcı metotumuzu statik olarak belirledik ve koleksiyonumuzu örnekledik .
}

public void UrunAl(Urun u)
{
alinanUrunListesi.Add(u); UrunAl metotumuzu kullanrak koleksiyonumuza yeni bir urun ekledik .
}

Şimdi form uzerindeki olusturdugumuz linklabel Ürünü Satın Al ın LinkClicked event ını kullanarak urunlerimizi ekleyelim .
Ilk olarak form un yapıcı metotunda AlinanUrunListesi tipimizi ornekleyelim ve adına a diyelim .

Helper h;
AlinanUrunListesi a;
public Form1()
{
InitializeComponent();
h = new Helper();
a = new AlinanUrunListesi();
}

Nesnemizi örnekledikden sonra ilgili olayımıza gidip kodlarımızı yazalım .

private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
a.UrunAl((Urun)lstUrunler.SelectedItem); a.UrunAl() metotumuz bisen Urun tipin deger istemektedir . lstUrunler.SelectedIrem (Urun) tipie cast edip bu sekilde parametre olarak verelim .

label12.Text = string.Format("Sepette {0} adet Ürün Wardir", AlinanUrunListesi.UrunSayisi);
Label12.text alinanurunlistesi.urunsayisi yani koleksiyonumuzun count degerini verelim ve urun miktarımızı görelim .
}

Şimdi uygulamamızı çalıştıralım ve biraz alışveriş yapalım :)

Alışverişimiz sırasında 10 adet urun aldık artık sepetimizde 10 adet urun bulunmaktadır .

Artık sepetimize ürünlerimizi attıgımıza göre gidip sepetimizi goruntuleye biliriz . Sepetimiz icerisindeki urunleri ve toplam fiyatlarını alalım .

Sepetimizdeki işlemleri goruntulemek icin yeni bir form olusturalim [form2]

Sepetim tıkladıgım zaman sepetimdeki urunlerimiz ve toplam ödeyecegim miktarı ögrenmek icin yeni bir form acmam gerekmektedir . bunun icin Sepetim linklabel uzerinde LinkClicked event ını kullanarak . yeni form umuzun gelmesini saglayalım .

private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Form2 f = new Form2();
f.Show();
}

Artık yapıcagımız işlemlerimiz Form2 tarafında olucaktır .

Form2 inceleyelim .

public partial class Form2 : Form
{
Form2 class ımız formdan kalıtılmış olup partial class olarak calısmaktadır. Partial class mantıgı c# 2.0 ile birlikde gelen bir kavramdır. Ne oldugu nasıl calıstıgını bir sonraki makalemizde derinlemesine inceleyecegiz .
AlinanUrunListesi a; AlinanUrunLİstesi a seklinde tipimizi point ettik .
Helper h; Helper ımızı poin ettik .
public Form2()
{
Form2 yapıcı metotu icerisinde pointer larımızı örnekledik ve bellege cıkmasını sagladık .
InitializeComponent();
a = new AlinanUrunListesi();
h = new Helper();
}

Form2 nesnemiz orneklendigi zaman yukarıdaki işlemler olmaktadır . Simdi Form_Load aşamasında sepetimizin oluşmasını icerisine verilerin atanması kısmına bakalm .

private void Form2_Load(object sender, EventArgs e)
{
lstAlinanUrunler.DataSource = AlinanUrunListesi.alinanUrunListesi;
FiyatTopla();


}

Form2 load kısmında yani yuklenme asamasında static olarak olusturdugumuz list koleksiyonumuz direk olarak cagrılmaktadır . zaten icinde urun bilgilerini tutugu icin hic bir isleme gerek kalmadan sepetimizi görebiliriz.

FiyatTopla metotumuz aşagıdak işlemleri yapmaktadır .

public void FiyatTopla()
{
decimal toplamRakam = 0;
foreach (Urun item in AlinanUrunListesi.alinanUrunListesi)
{
toplamRakam += item.Fiyat;
}
lblBilgi.Text = string.Format("Toplam Ödeyeceginiz Miktar {0:c}", toplamRakam);
}

FiyatTopla metotumuz iceride aşagıdaki işlemleri yapmaktadır .

• Decimal toplamRakam adında deger tipli bir degisken olusturmaktadır ve oluşturulma aşamasında 0 olarak deger almaktadır . Deger tipli degiskenlerimiz bellege bos bir sekilde cıkamazlar o yuzden herhangi bire deger alıp o sekilde bellekde yerlerini almalıdırlar .
• Foreach dongumuz ile sepetimizdeki toplam urun fiyatımızı bulmamız icin AlinanUrunListesi.alinanUrunListesi koleksiyonumuzda dönüp foreach döngümüz icerisinde toplamrakam += item.fiyat seklinde aldıgımız her urunumuzun fiyatını bu sekilde toplamalıyız .
• Lblbilgi.text isimli label ımıza en son olarak fiyat bilgimizi yazdıralım .
• ("Toplam Ödeyeceginiz Miktar {0:c}", toplamRakam burada {0:c} ile belirtmemizin sebebi current yazmasnı saglamaktır.

Uygulamamızı calıstıralım alısverislerimizi yapalım ve sepetimize bakalım .

Artık uygulamamızda rahatlık ile alış veriş yapıp istediğimiz ürünümüzü sepetimize aktarabilir ve sepetimizin içerisindeki ürünleri ve toplam fiyatlarını alabiliriz.

Bu kısma kadar uygulamamızı tamamladık son olarak şunu düşünelim. Ürünlerimizi şimdi almak istemiyoruz daha sonra alacağız bunun icin sepetimi kaydet link label tıkladığımız zaman gitsin bir yere bu bilgilerimizi binary olarak yazsın ve kaydetsin .

public void SepetiKaydet(string path, List<Urun> gelenUrun)
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream fs = new FileStream(path, FileMode.Create);
formatter.Serialize(fs,gelenUrun);
fs.Close();
}

Helper sınıfımız icerisinde binary donusturme kodlarımızı yazalım ve Sepeti Kaydet kısında ornekleyip kullanalım .

private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
h.SepetiKaydet("c:\\urunlerimiz.magaza", AlinanUrunListesi.alinanUrunListesi);
MessageBox.Show("Sepet Kaydedildi..");

}

Yukarıdaki gibi sepetimi kaydet butonuna bastıgımız zaman sepetimiz binary olarak gidip kendini belirledigimiz yere kaydedicektir.

Uygulama çalıştıgı zaman eger daha onceden yapılmış ve kaydedilmiş bir sepetimiz var ise bize sorsun desin ki

Sepetinizde n adet Urun var yuklemek istermisiniz.

Eger sepetimiz yok ise desin ki

Bu ilk alışverişiniz .

Kodlarımızı Form1 load kısmında yazalım .

Uygulama calıstıgı zaman ilk olarak form un yapıcı metotundan sonra load metotu calısıcaktır .

Form1_Load Kısmı …

Ilk Olarak sepetimizin olup olmadıgına bakalım .

public List<Urun> SepetiOku()
{
List<Urun> gelenUrunler = new List<Urun>();
;
BinaryFormatter bf = new BinaryFormatter();
if (File.Exists("c:\\urunlerimiz.emrah"))
{
FileStream fs = new FileStream("c:\\urunlerimiz.emrah", FileMode.Open);
gelenUrunler = (List<Urun>)bf.Deserialize(fs);
fs.Close();
}

Yukarıdaki metotumuz içerisinde gelenurun adında list<urun> koleksiyonu olusturduk ve if koşulunu kullanarak dosyamızın var olup olmama durumunu kontrol ettik eger dosyamız var ise filestream ile dosyamızı acıp BinaryFormatter . Deserialize metotu ile binary dosyamızı okuduk . metot imzamızda oldugu gibi list<urun> koleksiyon olarak verilerimizi geri dondurduk . Form load kısmında

if (h.SepetiOku().Count!=0 bu kısımda gidip metotumuz calıstırdık ve coun bilgisini aldık eger 0 a esit degil ise dedik ve eşit olmama durumunda sepetimize eski sepetimizi atadık . )
{
List<Urun> gelenUrunler=h.SepetiOku();
DialogResult res= MessageBox.Show(string.Format("Sepette {0} adet ürün war Yüklensinmi ?", gelenUrunler.Count),"Uyari", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
if (res == DialogResult.OK)
{
AlinanUrunListesi.alinanUrunListesi = gelenUrunler;
}

}
else
MessageBox.Show("Bu Ilk AlisVerisiniz");
}

Artık eski bir sepetimiz var ise uygulamamız ilk acıldıgı zaman sepetimizi bulucak ve bize sorucaktır evet olarak secer isek eski alışverişimiz yeni sepetimize yuklenecektir. Hayır der isek herhangi bir eskiden kalma alışveris yeni sepetimize yuklenmeyecektir.

Eger dosyamızı bulamaz ise else metotu calısıcak ve Bu Ilk AlisVerisiniz olarak bize mesaj vericektir .


Son not : Uygulamamız icerisinde herseyi class mantıgında kullanıp c# ın tum nimetlerinden yararlandık .

Cengiz Atilla
cengiz.atilla@hotmail.com

 

Urun Uygulamasi