C# Settings(Ayarlar) Dosyasının Kullanımı
Giris
.Net FrameWork 2.0 oturum ve uygulama arasında kalan degerlere erismemize ve yeni degerler olusturmamıza izin verir. Bu degerler "Settings" olarak adlandırılır. Settings dosyası kullanımına ihtiyaç duyulan uygulama bilgilerini yada kullanıcı ayarlarını temsil eder. Örnegin; uygulamanın renk seması için kullanıcı ayarlarını saklayan ayarları olusturabiliriz. Yada uygulamada kullanılan bir database’e belirlenen bir ConnectionString”i saklayabilirsin. Settings(Ayarlar) kullanıcıların ayarlarını saklayan profilleri olusturmamıza ve kodun uygulama dısında olan bilgilerine erismemize izin verir.
Uygulama Ve Kullanıcı Ayarları
Settings’lerin 4 adet özelligi vardır;
1. Name: Çalısma Zamanında ayarın degerine erismek için kullanılan addır.
2. Type: Ayarları temsil eden .Net Framework tipidir. Kullanıcı ayarlarını saklar.
3. Scope: Çalısma zamanında ayarlara nasıl erisilecegini temsil eden özelliktir.
4. Value: Ayarlara erisildiginde geriye döndürülecek olan degerdir.
Yeni Bir Settings Dosyası Olusturmak için;
1. Projemiz üzerinde sag tıklayıp, Add New Item
2. Settings Dosyasını seçeriz ve projemize ekleriz.
Settings dosyasını projemize ekledik, görünüm olarak biraz inceleyelim;
Yukarıda da belirttigimiz gibi Settings dosyalarının 4 adet özelligi var. Name, Type, Scope, Value.
Artık örnegimize geçelim ve olusturdugumuz Settings dosyasını kullanalım.
Örnek
Örnegimizde northwind database’ne baglanıp connection string’i Settings dosyası içerisinden çagıracagız. Formumuzun baslıgını, arka plan rengini ve font adını settings doyası içerisinden alacagız.
Formumuzun üzerine bir adet grid ekleyelim. Bu grid içerisinde Categories Tablosundaki kayıtları listeleyecegiz.
Simdi Kayıtlarımızı listeleyecek kodları yazalım.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace SettingsFile
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
SqlConnection Cnn;
SqlDataAdapter Dadp;
DataSet Dset;
private void Form1_Load(object sender, EventArgs e)
{
Cnn = new SqlConnection(sem.Default.ConnectionString.ToString());
// ConnectionString Degerini Settings dosyası içerisinden çagırdık.
Dadp = new SqlDataAdapter("Select * from Categories",Cnn);
Dset = new DataSet();
Dadp.Fill(Dset, "table");
dataGridView1.DataSource=Dset.Tables[0];
}
}
}
ConnectionString’i settings dosyası içerisinden kullandık. Simdi Form baslıgımızı, form backgroundunu ve gridimizin font ayarını settings dosyasından yapalım
this.Text = sem.Default.FormBaslıgı.ToString();
this.BackColor = sem.Default.ArkaPlanRengi;
this.Font = sem.Default.FormFondu;
Evet tüm ayarlarımızı settings dosyası içerisinden ayarladık. Görüldügü gibi form baslıgı, background rengi ve font family settings dosyası içerisinde belirledigimiz degerelere göre geldi.
Bu makalenin de sonuna geldik, baska bir makalede görüsmek üzere basarı ve iyi günler dilerim.
Sem GÖKSU
MCP | MCAD.NET | MCTS
Örnek Kodlar için mail adresimi kullanabilirsiniz
Kaynaklar
http://msdn.com
Namespace Nedir, Value ve Reference Type’ları Nedir?
Namespaces
Diger .Net dilleri gibi C#’ta .NET base class library’sinde tanımlanmıs datatype’ları kullanır. Bu classlar namespace adı altında gruplanmıstır. Namespace’e diger bir tanımlama ile classları kullanırken fonksiyonel bir sekilde ulasmamızı saglayan logic containerlar diyebiliriz. Örnek olarak System.Windows.Forms namespace’i ni verebilirim
1: namespace Desta.Deneme.DenemeClasses
2: {
3: public class a()
4: {
5: Public a(){}
6: private string dbname;
7: public string dbName
8: {
9: Get{return dbname;}
10: Set{dbname=value;}
11: }
12: }
13: }
using kelimesi ile de namespaceler içerisinde bulunan classları projemize dajil etmis oluruz.. namespace using ile projeye dahil edildikten sonra herhangi bir period belirtmeden namespace içerisinde bulunan tanımlamalara ulasabiliriz.
using Desta.Deneme.DenemeClasses;
böylece deneme namespace içindeki tüm classlara ve içinde bulunan property ve fonksiyonlara erisebiliriz.
using ile compile islemi sırasında modüller arasında herhangi bir link tanımlamıs olmayız.
using ile ilgili ilginç bir sey ise onu alias type tanımlamak için kullanabilmemiz. Asagıdaki örnek System.Int32 type’ını intecir adıyla kullanmamızı saglar.
1: using intecir=System.Int32;
2: public class AliasOrnek
3: {
4: public static intecir Main()
5: {
6: intecir i=1;
7: intecir j=i+1;
8: System.Console.WriteLine(j);
9: return 0;
10: }
11: }
System Namespace
Common Laguage Specification (CLS) bir programlama dili tarafından desteklenmesi kaçınılmaz olan bir çok datatype’ı tanımlayan zengin bir library’e sahiptir. Bu libraryde bulunan Boolean, string, integer, kronolojik ve finansal valueların hepsi System namespace’inin içerisinde yer alır.
Bütün typelar object type’ından inherit edilir. Böylece bir object’in referansı herhangi bir tipdeki degiskeni tutmak için kullanılabilir.
Long type’ın bit olarak büyüklügü 64′e çıkarılmıstır. Bu sayede Whistler ve XP platformlarında 64 bitlik programlar için bir hazırlık saglanmıstır. (64 bitlik olan bu isletim sistemleri Intel’in yeni nesil 64 bitlik islemcisi Itanium uyumludur)
System NameSpace i birçok alt kullanıcı barındırır.
System.Web
HTML ve Web kontrollerini ,güvenlik, sessionstate, konfigurasyon, bölgesel ayarlar gibi metodları barındırır.
System.Data
Genel olarak veritabanı islemlerimiz için kullandıgımız NameSpace’dir.
System.Windows.Forms
Windows Forms uygulamaları için özel ayarları barındırır.
System.Drawing
Yazdırma ve resim isleme ile ilgili islemlerde kullandıgımız NameSpace’dir.
System.XML
XML islemleri için kullanılmktadır.
süphesiz .Net Framework ün bize sundugu bu zengin kütüphane System NameSpace’i ile sınırlı degil.
Value ve Reference Tipleri
C# programlama dilinde bildiginiz gibi veri türlerini Reference Types Value Types olmak üzere iki kısma ayırıyoruz.
.NET dilleri tarafından kullanılan yada yaratılan her class value ve referans tipleri olarak kategorilendirilebilir. Value ve referans tipleri iki belirgin farklılık gösterir : hafızada tutuldukları yerler ve atama islemi içeriklerdeki davranıslarına göre.
Value tipler stackte tutulur, her iki value degeri için yapılmıs atama islemi ile hafızada birbirinin kopyası iki bölüm olusturulur. Referans tipler ise heap’de tutulur. Her iki referans degeri için yapılmıs atama islemi ile memory’deki tek bir yere iki ayrı referans olusturulur.
Asagıdaki kod parçasında bir referans türüne ve bir de deger türüne null degerler atanmaya çalısılmaktadır.
1: using System;
2: namespace c1
3: {
4: class c1
5: {
6: static void Main(string[] args)
7: {
8: string refTuru=null;
9: int dTuru=null;
10: }
11: }
12: }
13: Bu uygulamayı derlemeye çalıstıgımızda Cannot convert null to 'int' because it is a value type hatasını alırız. Aynı durumu kendi tanımladıgımız referans ve deger türleri içinde gerçeklestirebiliriz. Asagıdaki kod parçasında bu durum örneklenmistir.
14: using System;
15: namespace c2
16: {
17: class c2
18: {
19: }
20: struct Dvd
21: {
22: }
23: class C1
24: {
25: static void Main(string[] args)
26: {
27: Kitap kitap=null;
28: Dvd dvd=null;
29: }
30: }
31: }
Bu kod parçasındada aynı hatayı alırız. Çünkü struct’ lar deger türüdür ve bu sebeple null degerler alamazlar. Oysaki aynı istisnai durum class gibi kendi tanımlamıs oldugumuz referans türleri için geçerli degildir. Peki deger türlerinin null deger içerme ihtiyacı ne zaman dogabilir? Bir veritabanı uygulamasını göz önüne alalım. Bu tabloda int, double gibi deger türlerine karsılık gelecek alanların var oldugunu düsünelim. Veri girisi sırasında bu int ve double degiskenleri null olarak tabloya aktarmak isteyebiliriz. Ya da tablodan veri çekerken, deger türü karsılıgı alanların null deger içerip içermedigini anlamak isteyebiliriz. Iste bu gibi durumlarda deger türlerinin null veriler içerebilecek yapıda olması, kodumuzun ölçeklenebilirligini arttıracak bir yetkinlik olarak düsünülebilir. Veritabanları için geçerli olan bu senaryoyu göz önüne almadan önce C# 2.0 için deger türlerinin nasıl null veriler tasıyabilecegini incelemeye çalısalım. Deger türlerinin C# 2.0 için iki versiyonu vardır. Nullable deger türleri ve Non-Nullable deger türleri. Bir deger türünün null degerler içerecek tipte olacagını belirtmek için ? tip belirleyicisi kullanılır.
1: using System;
2: using System.Collections.Generic;
3: using System.Text;
4: namespace TestOfNullableValues
5: {
6: class P
7: {
8: static void Main(string[] args)
9: {
10: int? maas;
11: double? pi;
12: maas = null;
13: pi = null;
14: }
15: }
16: }
17: Yukarıdaki kod parçası sorunsuz olarak derlenecek ve çalısacaktır
18: Asagıdaki kod ile iki value degerine atama yapılmakta ve hafızada iki deger kopyası olusturulmaktadır. (kodu derleyip çalıstırmak için /unsafe switch'ini kullanın)
19: using System;
20: public class Simpleclass
21: {
22: public static int Main()
23: {
24: int i;
25: int j;
26: i=5;
27: j=i;
28: Console.WriteLine("i="+i);
29: Console.WriteLine("j="+j);
30: unsafe
31: {
32: if (&i==&j)
33: {
34: Console.WriteLine("i ve j'nin adresleri aynı");
35: }
36: else
37: {
38: Console.WriteLine("i ve j'nin adresleri farklı");
39: }
40: }
41: Console.ReadLine();
42: return 0;
43: }
44: }
45: Bu kod ise iki referans degerine atama yapmakta ve hafızadaki tek kopyaya ulasmaktadır.
46: using System;
47: public class ReferenceType
48: {
49: public int MyValue;
50: }
51: public class SimpleClass
52: {
53: public static int Main()
54: {
55: ReferenceType i;
56: ReferenceType j;
57: i=new ReferenceType();
58: i.MyValue=5;
59: j=i;
60: Console.WriteLine("i.MyValue="+i.MyValue);
61: Console.WriteLine("j.MyValue="+j.MyValue);
62: unsafe
63: {
64: if (i==j)
65: {
66: Console.WriteLine("i ve j aynı adreste");
67: }
68: else
69: {
70: Console.WriteLine("i ve j farklı adreste");
71: }
72: }
73: Console.ReadLine();
74: return 0;
75: }
76: }
Primitives olarak adlandırılan pek çok degisken tipi C#’da value tipi olarak kabul edilir : integer value tipi gibi. Aynı zamanda struct ile tanımlamanan user tipler’de value tipinde tanımlamalardır.
Bir sonraki makalemde görüsmek üzere
Collections
System.Collection NameSpace’i içerisindeki Collection Classının bazıları;
ArrayList
BirArray
CollectionBase
DictionaryBase
Hashtable
Queue dir.
Biz bu makalemizde CollectionBase sınıfına deginecegiz.
Ilk olarak bir C# Windows application projesi açalım.
Projemizde anlasılması kolay olsun diye SQL Server 2000 da Northwind içerisindeki Kategoriler tablosunu kullanacagız.
Ilk olarak projemize bir adet Class ekliyoruz. Clasın adını Kategori olarak belirliyoruz. Buradaki amacımız kategori sınıfına ait bir kategori nesnesi olusturmaktır. Çünkü Collectionlar nesnelerden türerler.
Classımızı ekledikten sonra veritabanımıza bir göz atalım. Veritabanımızda var olan alanlar, CategoryID, CategoryName ve Description alanlarıdır.
Artık Kategori Classımızı yazabiliriz
Kategori.cs
1: using System;
2:
3: namespace Collection
4: {
5:
6: public class Kategori
7: {
8: private int tKategoriNo;
9: private string tKategoriAdi;
10: private string tKategoriAciklama;
11:
12: public Kategori(){}
13:
14: public Kategori(string kategoriadi, string kategoriAciklama)
15: {
16: this.tKategoriAdi=kategoriadi;
17: this.tKategoriAciklama=kategoriAciklama;
18: }
19:
20: public int KategoriNo
21: {
22: get
23: {
24: return tKategoriNo;
25: }
26: set
27: {
28: tKategoriNo=value;
29: }
30: }
31:
32: public Kategori(){}
33:
34: public string KategoriAciklama
35: {
36: get
37: {
38: return tKategoriAciklama;
39: }
40: set
41: {
42: tKategoriAciklama=value;
43: }
44: }
45:
46:
47: public string KategoriAdi
48: {
49: get
50: {
51: return tKategoriAdi;
52: }
53: set
54: {
55: tKategoriAdi=value;
56: }
57: }
58:
59:
60: }
61: }
Kategori classı içerisinde Kategoriler tablosuna ait bir kategori nesnesi olusturduk.
Simdi bu nesneye ait bir Collection olusturabiliriz. Projemize bir adet daha class ekleyelim ve adını KategoriCollection.cs verelim.
1: using System;
2: using System.Collections;
3:
4:
5:
6: namespace Collection
7: {
8:
9: public class KategoriCollection:CollectionBase //Collection Classları CollectionBase sınıfından türer ve Collection base System.Collections namespace i içerisinde yer alır.
10: {
11: public KategoriCollection(){}
12:
13: /*Burada Collecsiyonunuza bir eleman eklemek için Add Fonksiyonu olusturuyoruz. Dısarıdan Kategori türünde bir kategori nesnesi alır.*/
14:
15: public int Add(Kategori kategori)
16: {
17: return this.List.Add(kategori);
18: }
19:
20: public int Add(string KategoriAdi, string KategoriAciklama)
21: {
22: Kategori Kategori =new Kategori(KategoriAdi,KategoriAciklama);
23: return this.List.Add(Kategori);
24: }
25:
26: public int Add(int kategorino, string KategoriAdi, string KategoriAciklama)
27: {
28: Kategori Kategori =new Kategori(kategorino,KategoriAdi,KategoriAciklama);
29: return this.List.Add(Kategori);
30: }
31:
32: /* Collectionumuzdan bir eleman silmek için bir void olustururuz. */
33:
34: public void Remove(Kategori kategori)
35: {
36: this.List.Remove(kategori);
37: }
38:
39: /*Kategori türünde this adında özel bir property olustururuz*/
40:
41: public Kategori this[int index]
42: {
43: get {return (Kategori)this.List[index];}
44: set{this.List[index]=value;}
45: }
46: }
47: }
Kategori Nesnemizi ve Kategori Collectionumuzu olusturdugumuza göre artık bu collectionu kullanabiliriz. Projemize bir adet daha class ekleyelim ve adını KategoriProvider.cs olarak verelim.
1: using System;
2:
3:
4: namespace Collection
5: {
6: public class KategoriProvider
7: {
8:
9: /* Static bir Connection olusturulur */
10:
11: private static System.Data.SqlClient.SqlConnection Cnn=new System.Data.SqlClient.SqlConnection(Genel.ConnectionString);
12:
13:
14: public KategoriProvider(){}
15:
16:
17: /* Verileri çekmek için GetAllKategori adında bir function olustururuz. Function KategoriCollection türndedir.
18: */
19: public static KategoriCollection GetAllKategori()
20: {
21: KategoriCollection kc=new KategoriCollection();
22: System.Data.SqlClient.SqlCommand Cmd=new System.Data.SqlClient.SqlCommand
23: ("Select * from Categories ",Cnn);
24:
25: System.Data.SqlClient.SqlDataReader Dr;
26:
27: Cnn.Open();
28:
29: Dr=Cmd.ExecuteReader();
30: while (Dr.Read())
31: {
32: kc.Add(
33: (int)Dr["CategoryID"],
34: (string)Dr["CategoryName"],
35: (string)Dr["Description"]
36: );
37: }
38:
39: Dr.Close();
40: Cnn.Close();
41:
42: return kc;
43:
44: }
45: }
46: }
Evet simdi her sey hazır. Artık collectionumuzu form üzerinde kullanabiliriz. Bunun için formumuza bir adet Datagrid ekleyelim.
Gridimizi ekledikten sonra form yüklenirken verileri göstermek için Form_Load eventi içerisine asagıda kodları yazarsak projemizi tamamlamıs olacagız.
1: private KategoriCollection Kc=new KategoriCollection();//Collectionumuzun instance ni olusturduk
2:
3:
4: private void Form1_Load(object sender, System.EventArgs e)
5: {
6: Kc=KategoriProvider.GetAllKategori();
7: dataGrid1.DataSource=Kc;
8: }
Evet projemizi tamamladıgımıza göre artık projeyi çalıstırabiliriz.
Iste sonuç
Evet arkadaslar makalemizin sonuna geldik bir sonraki makalemizde görüsmek üzere.
Asp.net Application Profiling
Birçoğumuzun gözden kaçırdığı, kaçırmasa da yapmayı ötelediği işlemlerdendir çalışan sistemin izlenmesi analiz edilmesi. Yazılmış kodların ya da çalışır bir sistemin profile edilmesi hızlı gelişen süreçler dahilinde lüks olarak nitelense de ayrılacak kısa süreler umulmadık çözümlere ulaştırabilir problemleri, gereksinimleri.
İşte bu gereksinimlerin öneminden yola çıkarak Profiling ve Monitoring araçlarını incelemeye çalışacağım kısa kısa.
İlk incelemek istediğim araç AutomatedQA adlı bir firmaya ait olan AQtime adlı bir uygulama. Performans
üzerine ürünler geliştiren bu firmanın AQtime ürününde hedeflenen performansa etki eden işlemleri izlemek ve memory kullanımını debug etmek. Ayrı olarak kullanılabildiği gibi Visual Studio içinden de kullanmak mümkündür. Deneme sürümünde her visual studio başlangıcında deneme sürümü confirmasyonu alması bir süre can sıkıcı gelebilir.
Native code için profile ve debug imkanı da veren bu uygulamada yapılandırmamızı asp.net uygulaması için yapıyor olacağız.
Asp.Net uygulamamızı Visual Studio 2005\2008 içerisinde açtıktan sonra proje özelliklerinden Build menüsü yardımıyla Debug işlemleri için Optimize Code seçeneğinin seçili olmadığından emin olalım. Bu seçimden emin olduktan sonra projeyi tekrar compile edelim.
Test edebilmek amacıyla basit birkaç for döngüsü kullanacağım bir web application oluşturdum. Bu web application in öncelikle iis e application olarak tanımlamamız ve virtual bir path vermemiz gerekli.
Test uygulamasıyla ilgili IIS yapılandırmasından sonra AQTime yapısına baktığımızda New Project seçeneğiyle yeni bir profiler projesi başlatıyoruz. Açılan bu projeyi IIS teki test sitemizle konuşturmak için bin folderı altındaki web uygulaması için assembly dll’ ini sol navigasyon menüsündeki Add Module seçeneğiyle projeye ekliyoruz.
Öncelikle test etmek ve izlemek istediğimiz uygulama Asp.Net uygulaması olduğu için Asp.Net modunu seçiyoruz. ![]()
Profile etmek istediğimiz aşamaları area alanından seçerek profiling işlemini başlatıyoruz. (Ingilizce bir kelimeye etmek fiili ekleyerek türkçeleştirmek en sevmediğim kullanımlardan biridir aslında ama profiling türkçe olarak daha mantıklı bir şekilde çeviremedim)
Run dedikten sonra karşınıza bir pencere daha çıkacaktır ve bu pencereden hangi işlemleri Runtime işlemlerini mi sonrasını mı vs izleme aşamalarını seçebilirsiniz.
![]()
Bu seçimi de yaptıktan sonra ayarların tamam olduğunu ve IIS uygulamasının başlatılmasının beklendiğini gösteren bir uyari göreceksiniz. Bu uyarıyla birlikte IIS uygulamasını Internet Explorerdan çağırmak AQtime ı aktif etmek ve izleme işlemine başlamak için yeterli.
Profiling esnasında uygulamanızda neler olup bittiğini hangi modullerin kaç saniyede ayaklandırıldığını sistemin nerelere eriştiğini erişemediğini monitor penceresinden izleyebilirsiniz.
Proje süreçlerinde zaman alması bakımından çokta üzerinde durulmaya ama zaman zaman harcanan zamanı kat kat fazlasını kazandıran işlemler olan Profiling ve Performans aşamalarındaki araçları incelemeye devam edeceğim.
Hata Yakalama (Exception Handling) – Hata Sınıfı Oluştumak
Bir önceki makalemizde kullandığımız hata sınıflarının tümü Exception sınıfına aitti. Programcılar bazı durumlarda kendi hata sınıfını oluşturmak isteyebilir. Kendi hata sınıfınızı hazırlarken hazırlayacağınız sınıf Exception ve ApplicationException sınıflarının mirasçısı olmalıdır. Aşağıda basit bir Exception sınıfı oluşturuyorum.
public class MyExceptionClass : Exception
{
public MyExceptionClass()
{
}
}
Oluşturduğum bu sınıfın metodu herhangi bir satıra ve parametreye sahip değil. Bu şekilde oluşturduğumuz Exception sınıfını herhangi bir uygulamada kullanabiliriz. Şimdi sınıfımız test edelim. Bunun için formuma bir buton koyuyorum. Click olayında 2 sayının birbirine eşit olup olmadığını kontrol edecek. Eğer sayılar birbirine eşit değilse Exception fırlatmasını istiyorum.
try
{
int a = 3;
int b = 5;
if (a == b )
{
MessageBox.Show(“Ok”);
}
else
{
throw new MyExceptionClass();
}
}
catch (MyExceptionClass ex )
{
MessageBox.Show(ex.Message);
}
throw keywordunu kullanarak programda bir hata olduğunu ve işlemin catch bloğuna düşmesini sağladım. Catch bloğunda ise hazırladığım exception nesnesinin orjinal mesajını kullanıcıya yansıttım.
Eğer kullanıcıya kendi hazırladığımız hata mesajını göstermek istersek MyExceptionClass sınıfında ki metodumuzun string bir değer alarak bunu kullancıya göstermesini sağlayabiliriz.
private string errorMessage;
public MyExceptionClass(string errorMessage): base(errorMessage)
{
this.errorMessage = errorMessage;
}
Sıfımızı bu şekilde güncelledikten sonra örneğimizi güncelleyerek sonucu görelim.
try
{
int a = 3;
int b = 5;
if (a == b)
{
MessageBox.Show(“Ok”);
}
else
{
throw new MyExceptionClass(“Sayılar birbirine eşit değil”);
}
}
catch (MyExceptionClass ex)
{
MessageBox.Show(ex.Message);
}
Bu şekilde kendi exception sınıfımızı üretebilir. Daha da detaylandırabiliriz. Önemli olan sınıfımızda doğru parametreler kullanarak sınıfımızı özelleştirmekten ibaret olacaktır.
Umarım yararlı olmuştur.
CrystalReports Export \ Export* uygulamasına farklı bir çözüm
Crystal Reports raporlama konusunda oldukça sık kullanılan bir üründür. Kolay geliştirilebilir olması ve veritabanıyla olan ilişkisinin kolay kurgulanabilir olması sık kullanılmasında en önemli etkenlerdendir.
DataSet ve DataTable yapılarıyla oluşturacağınız ReportDocument formatıyla istediğiniz formatta çıktı almanız mümkündür.
Export fonksiyonunu ek olarak ekleyeceginiz ExportOptions özellikleriyle kullanmanız gereklidir. Diğer özelliklerde Export özelliğinin daha spesifik versiyonlari olarak düşünülebilir.
ReportDocument rd = obj.MReportDocument;
ExportOptions options = new ExportOptions();
PdfRtfWordFormatOptions pdf = new PdfRtfWordFormatOptions();
DiskFileDestinationOptions destination = new DiskFileDestinationOptions();
destination.DiskFileName = @"c:\1.pdf";options.ExportDestinationType = ExportDestinationType.DiskFile;
options.ExportDestinationOptions = destination;
options.ExportFormatOptions = pdf;
options.ExportFormatType = ExportFormatType.PortableDocFormat;rd.Export(options);
Bu genel bilgilerin yanında esas olark yaşanabilecek bir raporlama sorununu ve bulduğum javascript destekli çözümü paylaşmak istiyorum.
Öncelikle sorunu belirtmek gerekirse iki tane raporun aynı anda pdf olarak bir aspx sayfasında Response edilmesidir. Sıkça karşılabileceğiniz üzere bir sayfada birden fazla rapor çıktısı istenebilir. Diğer bir deyişle, kullanıcının download etmeye zorlanması istenebilir. Ancak durumu ilginç kılan
ReportDocument.ExportToHttpResponse özelliğinin ilk response tan sonra bitirme işlemi yaparak Response u sonlandırmasıdır.
Bu sıkıntıyı aşmak için Crystal Reports dahil birçok ortamda cevap aramama karşın herhangi bir öneri bulamadım. Sorunu yaşayan çok fakat çözüm bulan hiç yoktu.
Bunun için ReportDocumentlerimi elde ettiğim sayfada her iki dokumanı da Current Cache ‘e yazdırdım.
ReportDocument rd =obj.MReportDocument;
HttpContext.Current.Application["asd"] = rd as object;
Daha sonra işlemi sadece raporu response edip yazdırmak olan boş bir aspx sayfası oluşturdum. (OpenReport.aspx)
Bu sayfanın içeriğinde Page Load aşamasını
ReportDocument rd = null;
if (HttpContext.Current.Application["asd"] != null)
rd = HttpContext.Current.Application["asd"] as ReportDocument;if (rd != null)
rd.ExportToHttpResponse(ExportFormatType.PortableDocFormat, HttpContext.Current.Response, true, "Report_" + DateTime.Today);
şeklinde düzenledim.
ReportDocumentlerimi cache e yazdığım ana sayfamda;
string url = "OpenReport.aspx?page=1";
string url1 = "OpenReport.aspx?page=2";Page.ClientScript.RegisterStartupScript(this.GetType(), "newWindow", string.Format("<script>window.open(‘{0}’);window.open(‘{1}’);</script>", url, url1));
Kod satırıyla işlem sonlandığında code behinddan çağırılacak olan scriptimi register ettim.
Açılan rapor sayfasında bir diğer seçenek olarak raporu stream olarak header ‘a da yazdırabilirsiniz. ExportToStream kullanacapımız bu yola başvurmamızın farkı dosyayı kaydettirmek yerine sayfa içinde gömülü olarak gelmesini istemektir;
MemoryStream stream = null;
ReportDocument rd = null;
if (HttpContext.Current.Application["asd"] != null)
rd = HttpContext.Current.Application["asd"] as ReportDocument;if (rd != null)
{
stream = (MemoryStream)rd.ExportToStream(ExportFormatType.PortableDocFormat);
}Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.BinaryWrite(stream.ToArray());
Response.End();
Özetlediğimizde;
- Ana sayfamda oluşturduğum iki ayrı rapor dosyasını Response a export etmek yerie cache e yazdım.
- Cache e yazma işleminden sonra popupta raporları açacak dosyamı register ettim.
- Açılan sayfada raporları export ederek her bir rapor için ayrı response nesnesi kullanmış oldum.
Umarım bu karışık ama çözüme giden yol bir gün işinize yarar.
Hata Yakalama(Exception Handling)
Merhaba bu yazımızda hata yakalama konusu üzerinde duracağız. Geliştirme yaparken farkında olmadan bir çok mantıksal hata yapabilir, run-time’da bu hataların acısını çekerek programınızın sonlandırılmasını izleyebilirsiniz. İşte hata yakalama, run- time’da oluşan ve programızın sonlandırılmasına neden olan hataları yakalamamızı sağlayan ve bu hataların yönetilebilir bir duruma getiren mekanizmadır.
Bazı hataları öngörebilir, bu hatalara gerekli önlemleri siz kod yazarken alabilirsiniz. Peki öngöremediğiniz hatalarda ne olacak? Bu durumda .Net hata yakalama mekanizması devreye giriyor.
Hata yakalama mekanizması nasıl çalışır?
Aslına bakacak olursak .Net için tüm hatalar bir nesnedir. Oluşan tüm hatalar System.Exception sınıfından türemektedir.Eğer sizin yakalayamadığınız bir hata oluşursa Common Language Runtime bunu yakalar ve programınızın sonlanmasına sebep olur.
Oluşan bu hata nesnelerini nasıl yakalayıp, nasıl yöneteceğiz?
Hata yakalama ve yönetme işlemini aşağıdaki kod bloğunu yazarak gerçekleştireceğiz.
try
{
//Hata oluşabilecek hata kosu bu bloğa yazılır
}
catch
{
//Hata oluşursa bu blok devreğe girer hatayı yakalar ve işler.
}
finally
{
//Hata oluşssada, oluşmasada çalışması istediğimiz bir kod varsa bu bloğa yazılır.
}
Bunu bir örnek ile açıklayacak olursak.
try
{
List<int> numbers = new List<int>();
for (int i = 0; i < 10; i++)
{
numbers.Add(i);
}
MessageBox.Show(numbers[15].ToString());
}
catch (Exception ex)
{
MessageBox.Show(“Hata Mesajı: ” + ex.Message);
MessageBox.Show(“Hatanın oluştuğu kısım: ” + ex.StackTrace );
}
finally
{
Application.Exit();
}
Bu örneğimizde bir sayı koleksiyon oluşduk. Bu sayı koleksiyona ona kadar olan sayıları ekledik. Ama indexi 15 olan bir sayıyı mesaj kutusunda göstermek istedik. Dolayısıyla bu kod parçası hataya düşecektir. catch bloğunda tanımlanan ex Exception nesnesine ait property olan Message bize bu hatayı bir mesaj kutusunda gösterecek, diğer bir property olan StackTrace bize bu hatanın oluştuğu adımı başka bir mesaj kutusunda gösterecek finally bloğunda yer alan Application.Exit() kodu programımızı sonlandıracaktır.
Hata Mesajı:
Hatanın oluştuğu kısım:
finally bloğunda yapabileceğiniz durum kodun davranışına göre değişebilir. Örneğin try bloğu içerisinde bir sql bağlantısı oluşturdunuz ve açtınız. bağlantıyı kapattığınız satıra daha gelmeden bir hataya düşerek catch bloğuna düştünüz. Dolayısıyla bağlantınız açık kaldı. Finally bloğunda bu bağlantıyı kapatabilirsiniz.
Birden fazla catch bloğu kullanmak
try
{
List<int> numbers = new List<int>();
for (int i = 0; i < 10; i++)
{
numbers.Add(i);
}
numbers = null;
MessageBox.Show(numbers[15].ToString());
}
catch (NullReferenceException ex)
{
MessageBox.Show(“Hata Mesajı: ” + ex.Message);
MessageBox.Show(“Hatanın oluştuğu kısım: ” + ex.StackTrace);
}
catch (Exception ex)
{
MessageBox.Show(“Hata Mesajı: ” + ex.Message);
MessageBox.Show(“Hatanın oluştuğu kısım: ” + ex.StackTrace);
}
finally
{
Application.Exit();
}
Bu kodda bir catch bloğu ekleyerek ex NullReferenceException nesnesi yardımıyla boş değerden kaynaklanan işlem hatalarını yakalamaya çalışacağız. Bir önceki örneğimizde kullandığım numbers koleksiyonuna boş değer set ederek boş bir koleksiyonun indeksine ulaşmayı istemek bana bu hata mesajını döndürecektir.
Hata Mesajı:
Hatanın oluştuğu kısım:
Birden fazla catch bloğu kullandığımız zaman catch blokları sırası ile değerlendirilir. Oluşan hata ilk hangi bloğa uyuyorsa o blokta çalıştırılır ve diğer bloklar dikkate alınmaz. Bu nedenle catch bloklarımız oluştururken tüme varım ilkesiyle hareket etmemiz daha iyi olacaktır. Yani özelden genele doğru bir hata yakalama işlemi yapmamız gerekmektedir. Aynı yukarıdaki örnek gibi.
Bir sonraki makalemde kendi hata sınıflarımızı yaratarak kullanacağız.
İyi çalışmalar.
İş Dünyasında Raporlamanın Önemi
Günümüz iş dünyasında raporlama dendiğinde anlaşılan bir iş sürecinin durumunun ya da sonucunun, ilgili kişilere, önceden belirlenmiş bir biçimde, önceden belirlenmiş yöntemlerle bildirilmesi anlaşılır. Doğrusuda budur elbette. Ancak bu makalenin konusu teknik raporlamadan ziyade, iş hayatında üstlerin ve ilgili kişilerin bilgilendirilmesi olacak.
İş hayatında hepimiz belirli kişi ya da kurumlara karşı sorumluluk taşırız. Özel şirketlerde üstlerimiz vardır. En üstteysek işletmenin ortakları vardır. Halka açık şirketse çok daha geniş bir kitleye karşı sorumluluk taşırız. Devlet kurumlarında da en alttan en üste doğru ilerleyen bir sorumluluk zinciri olmakla birlikte, en üst noktaya gelindiğinde halka karşı bir sorumluluk vardır. Dolayısıyla bu sorumluluk zincirini en üst basamağı olmayan bir piramit yapısı olarak kabul etmektense, bir çember olarak görmek daha doğrudur diye düşünüyorum.
Peki ister özel bir işletmede çalışalım, ister devlet kurumunda. Raporlama dendiğinde ne anlamalıyız? Raporlamayı kime karşı yapmalıyız? Nasıl yapmalıyız? Sorumluluğumuz sadece raporlamak mıdır? Yoksa yaptığımız işin ve verdiğimiz raporların takipçisi olmak mıdır?
Bu güne kadar yazdığım 200 küsür makalenin hepsinde işe IT gözlüğüyle baktığımı farkettim. Bu makalede bu çerçevenin biraz dışına çıkmak istiyorum. Ancak elbette IT tarafında kazandığım deneyimlerin, iş dünyasına uyarlanabilirliğinden faydalanıyor olacağım.
Başarısızlığın Temel Nedenleri
Bir IT projesinde başarısızlığın en temel nedenlerini düşündüğümde aklıma gelen en önemli neden “zayıf iletişim” oluyor. Peki iletişim nasıl güçlü olur? Sürekli yazışmak ya da konuşmak, güçlü bir iletişim mekanizmasının varlığını mı gösterir? İletişimin sürekliliği ve yoğunluğu kadar, aktarılan bilginin kaliteside önemlidir. Sağlıklı bir iletişimin temel unsurlarını şu şekilde sağlayabiliriz;
- Düzenli iletişim
- Aktarılan bilginin kalitesi
- Aktarılan bilginin anlaşılabilirliği
Çalışma arkadaşlarımızla belirli bir frekansta iletişim kuruyor olmak elbette önemlidir. Ancak iletişimin sıklığından çok, doğru zamanda iletişim kurmak ve paylaşılan bilginin kaliteli olmasını sağlamak önemlidir. Yapılan bir işin durumu hakkında bilgilendirme yaparken aktarılan bilginin kalitesi kadar önemli olan bir başka konu ise karşı tarafın anlamak için fazla zaman harcamasını gerektirmeyecek şekilde sunulmasıdır. İletişim gerektiğinde sözlü olabileceği gibi (sonradan mutlaka yazıya dökülmelidir), gerektiğinde bir email, gerektiğinde bir excel ya da word dosyası gerektiğinde ise daha gelişmiş raporlama araçları kullanılabilir.
Gerektiğinde Yardım İsteyebilmek Önemlidir
Bilginin paylaşımı sadece insanların iş süreçlerinden haberdar olmasını değil, olası problemleri öngörebilmesini ve müdahale edilmesi gereken noktaların belirlenebilmesini de sağlar. Türkiye’de içinde bulunduğum projelerde en sık gördüğüm sorunlardan biri, insanlarımızın yardım isteme konusundaki çekingenliğidir. Nedenleri bu makalenin konusu olmamakla birlikte bu çekingenlik, üst yönetim tarafından zamanında algılanamaması halinde iş süreçlerinin başarısızlığında ciddi rol oynar.
Bu noktada raporlamanın bir başka çeşidinden bahsetmiş oluyoruz. Günümüz iş dünyasında raporlama dediğimizde sadece bir iş sürecinin o anki durumu ya da gidişatı ile ilgili bilgilendirmeyi değil, olası risklerle ilgili bilgilendirmeyi de kastediyor olmalıyız. İleriye yönelik risklere karşı risk yönetim planları oluşturabilmemize olanak tanıdığı için bu raporlamanın değeri, çoğu durumda verilen durum raporlarından çok daha yüksektir.
Yazılı İletişim Önemlidir
Peki raporlama hangi platformda olmalıdır? Eminim şu cümleleri defalarca duymuşsunuzdur;
- Ben söylemiştim
- Biz size bunu şöyle anlatmıştık
- Size nasıl olması gerektiğini x anlatmış olmalı
- X size söylemedi mi?
- Öyle mi konuşmuştuk? Unutmuşum!
Bu cümlelerin onlarca benzerini duymuşsunuzdur. Dikkat ederseniz hepsinin ortak özelliği “sözlü iletişim”e dayanmasıdır. Sözlü iletişim elbette önemlidir. Hatta bazı durumlarda iletilmesi gereken bilginin, yazıya dökülmesine zaman olmayabilir. Ancak bu, bu bilgi aktarımının daha sonra yazıya dökülmemiş olmasına bahane değil. Sözlü iletişimin yazıya dökülmesi, ‘sekreter işi’ olarak görülür genelde. Bu kesinlikle yanlış bir görüştür. Bu hem sizin, hem karşı tarafın korunması için son derece önemli bir iştir. Konuşulanların yazıya dökülmesi yukarıda bahsettiğim cümlelerin duyulmasını engelleyecek, yani iki tarafın birbirini doğru anlamasını garanti edecektir. Bununla birlikte gerekli durumlarda kendinizi ve kurumunuzu savunmanız için son derece güçlü bir dayanak olacaktır.
Savunmak?
Malesef evet. Ama işler sadece bizim ülkemizde böyle yürümüyor. Dünyanın hangi ülkesinde iş yaparsanız yapın, işler istendiği gibi gitmediği anda insanlar bir ‘suçlu’ arıyor. Hatta kendilerini bu suçlu arayışına o kadar kaptırıyor ki, ortadaki istenmeyen durumun düzeltilmesine harcamaları gereken değerli zamanı, birbirlerini suçlayarak geçiriyorlar. İşte bu noktada gereksiz tartışmalara bir son verebilmenin ve işin nasıl planlandığını, mutabakatın nasıl olduğunu ortaya koymanın en iyi yolu, iletişimi yazılı hale getirmektir. Bu ‘yazılı hal’, işin detaylarının tartışıldığı aşamalarda toplantı notları ve emailler, daha ileri aşamalarda proje planları ve emailler, daha ileri aşamalarda ise ilerleme raporları, emailler ve benzeri dokümanlar olacaktır. Elbette bu saydığım ‘yazılı hal’ler çeşitlendirilebilir.
Verileri Merkezileştirmek
İletişimi yazılı hale getirmek tek başına yeterli değildir. Verileri merkezileştirmek ve ihtiyaç duyan kişinin, ihtiyaç duyduğu veriye, ihtiyaç duyduğu anda, kolayca ulaşabilmesini sağlamak gerekir. Elbette bu bilgi merkezine erişim çeşitli yetkilendirmelerle olabilir. Ancak onlarca inbox’ta ve diskte toplanmış, binlerce email ve doküman arasından istenilen bilgiye ulaşmak, sözlü iletişimin egemen olduğu iş süreçlerinde doğru bilgiye ulaşmaya kıyasla sadece ‘biraz’ daha kolaydır.
Kurumlar, iş süreçlerinde oluşan bilgileri, doğru bir sınıflandırma ile, yüksek erişilebilirlik sağlayan ve iş süreçlerinin üyelerinin arama yapmasına olanak veren bir altyapı ile merkezileştirmelidirler.
Ve tekrar raporlamak
Uzun iş süreçlerinde isteyelim ya da istemeyelim çok miktarda veri oluşur. Bu veriler farklı kullanıcılar tarafından, farklı zamanlarda oluşturulur. Bu verilerin, gerekli zamanlarda özetlenerek, ilgili kişilerle paylaşılması gerekebilir. Örneğin bu bilgiler bir proje toplantısı öncesinde projenin durumu ile ilgili bilgiler kronolojik olarak toplanarak bir durum raporu oluşturulabilir. Ya da bir proje teklifi öncesinde, yapılan görüşmelerde ve analizlerde ortaya çıkan bilgiler derlenerek zaman, iş gücü ve maliyet hesaplaması yapılmasında kullanılabilir.
Bu yazılı iletişim mimarisi doğru tasarlandığı ve uygulandığı taktirde sadece sağlıklı bir iletişim ve raporlama mekanizması görevi görmekle kalmayacak, bize farklı iş süreçlerini kıyaslama ve iş süreçlerindeki hatalarımızı daha net görerek önlem alabilme imkanı verecektir.
Bu makalede kendi deneyimlerimden yola çıkarak, iş hayatında raporlama ve yazılı iletişimin önemine değinerek doğru bir yazılı iletişim mimarisinin nasıl olması gerektiğini ve doğru bir yazılı iletişim mimarisinin sağlayacağı faydaları vurgulamaya çalıştım. İdeal sistemi tasarlamak belki bir defada yapılabilecek bir şey değil ve belki her kurum için ideal sistemin özellikleri farklılık gösterecektir. Ancak temel özelliklerin ortak olacağı ve bu tür bir yapının ve çalışma modelinin oluşturulması için harcanacak zaman ve iş gücünün geri dönüşünün çok hızlı olacağını ve bu sürecin kuruma maliyetinin çok ötesinde bir getirisi olacağını öğrenmemiz gerekiyor. IT sektörü başta olmak üzere pek çok alanda çok büyük ve hızlı ilerlemeler kaydediyoruz. Bu büyüme sırasında, bazı alışkanlıklarımızdan vazgeçerek iş süreçlerimizi yeniden modellememiz gerektiğini, umarım olumsuz deneyimlerle karşılaşmadan farkedebilir ve harekete geçebiliriz.
C# And API’s
Merhaba, bu makalemde sizinler API yapisi uzerinde inceleme yapip ufak bir ornek yapmayi planliyorum.
API (Application Programming Interface) Programlar ve Islemci arasinda, komutlardan olusan bir arayuzdur. Genellikle Microsoft’un kendi komutlarindan olusur (Shutdown, Reboot, Open-Close CD-Rom etc.). Windows API’si binlerce fonksiyon, structure, bazi constantlardan olusur (kendi projelerinizde kullanabileceginiz). Bu fonksiyonlar C dili ile yazilmistir, dolayisiyla bunlari kullanmadan declare etmeniz gerekmektedir. DLL proseduru icin declaration islemi biraz kompleks bir sekilde olur. API declaration icin API Viewer kullanabilirsiniz. Bir cok ileri derece programlama dili API Programlamayi destekler. The Microsoft Foundation Class Library (MFC), yuklu miktarda Win32(API) icerir. ODBC API fonksiyonlari, database’de hizli islemler yapmaniza olanak saglar. API ile, uygulamaniz isletim sisteminizdeki dusuk dereceli (lower-level) servislere request atabilir. API binlerce fonksiyonalite destekler. MessageBox’dan Encryption veya Remote Computinge… Bir developer, API’yi kendi programina entegre etmeyi iyi bilmelidir.
APIlerin kullandiginiz isletim sistemi, islemci turune gore cesit cesti tipler icerebilir.
Isletim Sistemi bazli API:
Her bir isletim sistemi API’nin yaygin tiplerine sahiptir.
Ornegin;
Windows NT MS-DOS destekler. Win16,Win32,POSIX (Portable Operating System Interface), OS/2 console API ve Windows 95, MS-DOS, Win16, ve Win32 APIlerini destekler.
Win16 & Win32 API:
Win16, 16-Bit islemciler icin API ile yaratilmistir, ve 16 bitlik degerlere dayanir. Ornegin, Win16 programlarinizi MS-DOS’a baglayabilirsiniz (TSR programlari gibi).
Win32 ise Win16 ile ayni sekilde yaratilmis olup, 32-Bit islemciler icindir, ve 32-Bit’lik degerler kullanir.
Win32 API libraryleri isimlerinden sonra ‘32’ ifadesini icerir. (KERNEL32, USER32 gibi.)
Tum apiler 3 adet kutuphane ile implement edilmistir.
-Kernel
-User
-GDI
1-KERNEL
Kernel, KERNEL32.DLL isminde bir kutuphanedir, ve isletim sistemi’nin yeteneklerini icerir.
-Process Loading
-Context Switching
-File I/O
-Memory Management gibi..
Ornek olarak GlobalMemoryStatus fonksiyonu,size sistemin anlik kullandigi olarak kullandigi fiziksel ve sanal bellek boyutunu gosterir.
2-USER
User, USER32.DLL isminde bir kutuphanedir, ve bu kutuphaneyi kullanaraktan tum kullanici arayuzlerinin yonetimini saglayabilirsiniz.
-Windows
-Menus
-Dialog Boxes
-Icons gibi…
Ornek olarak DrawIcon fonksiyonu, belirtilen noktada size icon veya cursor cizer..
3- GDI (Graphical Device Interface) :
GDI, Win32 tabanli isletim sistemlerinde GDI32.DLL isminde, grafik cikis kutuphanesidir. Windows GDI kullanaraktan, menuleri dialog boxlari cizer. GDI, bir noktada imagelarin saklanmasinda da gorev alir.
Ornek olarak CreateBitmap fonksiyonu, belirtilen ozel olculerde, renklerde bitmap yaratir.
C# Ve API Arasindaki Iliski
APIleri C# icerisinde implement etmek, yazilima yeni baslayanlar icin agir bir istir. Boyle bir islem yapmadan once, bilmeniz gereken bazi basliklar vardir. Bunlara ornek olarak, Structure Implement in C# , type conversion, safe/unsafe code, managed/unmanaged code, ve daha bir cok.
Kompleks APIlerin implementasyonunun once, basit bir MessageBox API implementasyonu ile baslayalim. MessageBox API’sine kod implement etmeden once basit bir Windows Application yaratalim, Form’a bir tane button ekleyin ve Button’un click eventinde Message Box’da kod gosterelim. Tabii ki bu islem icin harici bir kutuphane kullanacagiz.
Kullanilacak NameSpace:
using System.Runtime.InteropServices;
Ve simdiki satira dikkat! Bu satirda API’ deklarasyonu yapiyoruz:
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
Unmanaged Code’dan cagrilacak method icin DLL importu yaptik, “USER32” ifadesi ise hangi DLL’i import edecegimizi belirtmek amacli kullanilmistir. Kullanmis odugumuz MessageBox(), integer donduren, ve 4 parametre alan bir fonksiyondur.
Bir cok API degerleri kullanmak ve getirmek icin structure yapisi kullanir.
Button’un click eventine asagidaki kod blogunu ekleyelim
protected void button1_Click (object sender, System.EventArgs e) { MessageBox (0,"API Message Box","API Demo",0); }
Uygulamanizi Run ettiginiz zaman, APi fonksiyonunu kullanarak cagirmis oldugunuz bir messagebox goreceksiniz.
Birde structure kullanaraktan bir ornek yapalim.
Structure ile calismak, komplex APIler kullanir, veya structure icerisinde structure kullanir. Bu islemlerler siradan basit bir API kullanmaktan daha zordur. Structure ornegimde GetSystemInfo API’sini kullanaraktan, varolan sistem bilgilerini cekecegim.
Yeni bir C# formu acin, ve bir tane button ile listbox ekleyin. Kod tarafina asagidaki namespace’i ekleyin
using System.Runtime.InteropServices;
Declare structure, GetSystemInfo’nun bir parametresidir. Ustteki kod blogunun hemen ardindan
[StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; }
API fonksiyonun deklarasyonu: bu islem icin kernel32.dll’ini import ediyoruz.
[DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI);
1: protected void button1_Click (object sender, System.EventArgs e)
2:
3: {
4:
5: try
6:
7: {
8:
9: SYSTEM_INFO pSI = new SYSTEM_INFO();
10:
11: GetSystemInfo(ref pSI);
12:
13: //
14:
15: //
16:
17: //
18:
19:
20:
21:
22: listBox1.Items.Insert(0,pSI.dwActiveProcessorMask.ToString());
23:
24: //
25:
26: //
27:
28: //
29:
30: }
31:
32: catch(Exception ex)
33:
34: {
35:
36: MessageBox.Show (ex.Message);
37:
38: }
39:
40: }
Application’ i Run ettikten sonra, sekildeki gibi sistem bilgilerini goruntuleyebileceksiniz.
Microsoft .Net Framework 4.0 – Chart Technology (PART II)
Bir onceki yazimda, chart hakkinda ufak bir bilgi verip, source kodlari ile yapilisi hakkinda bir ornek yapmistim. Bu makalede, olayi biraz daha ust bir boyuta tasiyip, kullanacagimiz chart’a DataBind yapip, kod tarafinda dinamik bir chart olusturacagiz. Senaryo olarak, bir ogrencinin quizlerinden, midtermlerinden, ve finalinden almis oldugu notlari bir chart kullanarak raporlayacagim.
SQL – Serverda kullanacagim veriler icin altyapiyi olusturalim. Ogrenci tablosu icinde ogrencinin Adi-Soyadi, Quiz1, Quiz2, Quiz3, Quiz4, Quiz5, Midterm1, Midterm2, ve Final isimli fieldlarim olsun.
Sekilde gordugunuz gibi iki ogrenci icin Quiz,Midterm, ve Final notlarini DB’de tutuyorum.
Algoritmamiza gore oncelikle, datanin tutulacagi bir DataTable olusturuyoruz, ardindan data’yi cekip olusturdugumuz DataTable’a Bind ediyoruz, ve Fieldlardaki degerleri Chartimizda olmasi gereken yerlere set ediyoruz. Asagidaki kod blogunu uygulayarak.
Oncelikle .aspx sayfamiza bir tane Chart surukleyip birakiyoruz, ve gereken degerleri set ediyoruz:
1: <asp:Chart ID="studentGradesChart" runat="server">
2: <Series>
3: <asp:Series Name="Student" ChartType="Line" YValuesPerPoint="2">
4: </asp:Series>
5: <asp:Series Name="Student2" ChartType="Line" YValuesPerPoint="2">
6: </asp:Series>
7: </Series>
8: <ChartAreas>
9: <asp:ChartArea Name="ChartArea1">
10: </asp:ChartArea>
11: </ChartAreas>
12: </asp:Chart>
Ve sayfamizin Page_Load kismini bu kodlari koyuyoruz.
1: if (!Page.IsPostBack)
2: {
3: // DataTable olusturma
4: DataTable dt = new DataTable();
5: dt.Columns.Add("Isim", typeof(string));
6: dt.Columns.Add("Soyisim", typeof(string));
7: dt.Columns.Add("Quiz1", typeof(int));
8: dt.Columns.Add("Quiz2", typeof(int));
9: dt.Columns.Add("Quiz3", typeof(int));
10: dt.Columns.Add("Quiz4", typeof(int));
11: dt.Columns.Add("Quiz5", typeof(int));
12: dt.Columns.Add("Midterm1", typeof(int));
13: dt.Columns.Add("Midterm2", typeof(int));
14: dt.Columns.Add("Final", typeof(int));
15: dt.AcceptChanges();
16:
17: // istenilen datayi cekiyoruz
18: StudentObjectModelDataContext dc = new StudentObjectModelDataContext();
19:
20: List<Student> secilenOgrenciler = (from s in dc.Students select s).ToList();
21:
22: foreach (Student ss in secilenOgrenciler)
23: {
24: // Datayi, satirlara yerlestiriyoruz.
25: object[] row = new object[]
26: {
27: ss.StudentName,
28: ss.StudentLastName,
29: ss.Quiz1,
30: ss.Quiz2,
31: ss.Quiz3,
32: ss.Quiz4,
33: ss.Quiz5,
34: ss.Midterm1,
35: ss.Midterm2,
36: ss.Final
37: };
38: dt.Rows.Add(row);
39: }
40:
41: // Gelen Datayi, DataTable'a bagliyoruz
42: studentGradesChart.DataSource = dt;
43:
44: // Chart tipi secimi. Bu asamada bircok cesitten istediginizi secebiliyorsunuz.
45: studentGradesChart.Series["Student"].ChartType = SeriesChartType.Line;
46: studentGradesChart.Series["Student2"].ChartType = SeriesChartType.Line;
47:
48: int seriesIndex = 0;
49: foreach (DataRow dr in dt.Rows)
50: {
51: // Bu sekmede chart ozelliklerini customise ediyoruz.
52: // Kullanisli olan bircok property mevcut
53: studentGradesChart.Series[seriesIndex].MarkerStyle = MarkerStyle.Cross;
54: studentGradesChart.Series[seriesIndex].MarkerSize = 8;
55: studentGradesChart.Series[seriesIndex].MarkerBorderWidth = 7;
56: studentGradesChart.Series[seriesIndex].ToolTip = String.Format("Student Number : {0}", seriesIndex + 1);
57:
58: // Degerleri Chart'a set ediyoruz.
59: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 1", dr["Quiz1"]);
60: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 2", dr["Quiz2"]);
61: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 3", dr["Quiz3"]);
62: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 4", dr["Quiz4"]);
63: studentGradesChart.Series[seriesIndex].Points.AddXY("Quiz 5", dr["Quiz5"]);
64: studentGradesChart.Series[seriesIndex].Points.AddXY("Midterm 1", dr["Midterm1"]);
65: studentGradesChart.Series[seriesIndex].Points.AddXY("Midterm 2", dr["Midterm2"]);
66: studentGradesChart.Series[seriesIndex].Points.AddXY("Final", dr["Final"]);
67:
68: seriesIndex++;
69: }
70: }
Kod’u Run ettigimizde sekildeki gibi bir goruntu elde ediyoruz:
Elimden geldigince fikir edinmek adina, bir ornek yaptim. Tabii ki Chart konusu son derece derin bir konu. Bu konu ilgili bilgi edindikce bunlar ile ilgili ornekler yapmaya devam edecegim. Islerimin yogunlugundan firsat bulursam, bir sonraki asamada bir sirkete bagli olan alt kurumlarin ay bazinda yapmis oldugu cirolari gosteren bir chart yapmayi planliyorum.
Serkan Hekimoglu.












