XP Stilinde Kontroller ile Çalışma
XP Stilinde Kontroller ile Çalışma
Bu yazımızda Windows Form kontrollerinin veya nesnelerinin Windows XP stili görünümlerini nasıl elde edebileceğimizi göreceğiz.
Microsoft Framework v1.1’ de bu özellik henüz pratik bir şekilde yok. Bu yüzden yolumuz biraz uzun.
Elde edeceğimiz bu görünüm Windows Xp’ den önceki işletim sisteminde haliyle görünmeyecek, o işletim sisteminin default haliyle görünecektir(mesela butonlar önceki işletim sistemlerinde gri renkli görünüyordu).
Herhangi bir karışıklık çıkmaması için yönergeleri beraber takib edelim.
Hemen işlem adımlarımıza başlayalım:
Microsoft Visual Studio.NET’ i açın.
File/New/Project’ i tıklayın.
Açılan Pencerede Project Type alanında Visual C# Project seçili olsun.
Aynı pencerede Templates alanında Windows Application seçili olsun.
Aynı pencerede Name alanına XPStyle yazın.
Aynı pencerede Location alanında mevcut yolun sonundaki klasör isminide XPStyle yapın.
Projenin açılması için Okey butonuna tıklayın.
Şimdi Form1.cs[Design] görünümüne sahipsiniz.
Formumuza ; Button, radioButton, checkBox, textBox, progressBar ve trackBar ekleyin.
Button, radioButton, ve checkBox nesenelerinin Properties penceresinde Flat Style kısmını System yapın.
Düğerleri için bunu yapmaya gerek yok.
Menüden File/Save All tıklayın ve Menuden Build/Build Solutin tıklayın.
Elimizde mevcut bir görünüm oluştu, Projeyi bu haliyle çalıştırırsanız(Debug/Start),
Form elemanlarında XP Stilini göremeyeceksiniz,
Mesela Buton hala aşağıdaki gibi gri renkte görünecek.
Şimdi XP Stil görünümünü elde etmek için yönergeleri izleyin:
Menüden, Project/Add Class tıklayın.
Açılan pencerede Templates kısmında XML File(herhangi bir .cs dosyası da olabilir) seçin.
Aynı pencerede Name kısmındaki alanı tamamen temizleyin.
“[Proje Adı].exe.manifest” yazım biçiminde XPStyle.exe.manifest yazın.
Bu projenin adını XPStyle olarak belirlemiştik
Dosyamızın oluşması için OK butonuna tıklayın.
Oluşturduğumuz XPStyle.exe.manifest adlı dosyayı açın ve içine aşağıdaki kodları yapıştırın.
| <?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<assembly xmlns=”urn:schemas-microsoft-com:asm.v1″ manifestVersion=”1.0″> <assemblyIdentity version=”1.0.0.0″ processorArchitecture=”X86″ /> <description>.NET control deployment tool</description><dependency> <dependentAssembly> <assemblyIdentity version=”6.0.0.0″ processorArchitecture=”X86″ publicKeyToken=”6595b64144ccf1df” /> </dependentAssembly> </dependency> </assembly> |
NOT: “<” “>” karakterlerinin < ve > haline dönüşmesi söz konusu olabilir. Bu yüzden bu kodları önce bir NotePad’ e yapıştırın sonra buradan Select All deyip tekrar kopyalayın ve XPStyle.exe.manifest dosyamıza yapıştırın.
Bu kodda <Executable Name> kısmına Projemizin adı olan XPStyle yazın
Yeni hal: şeklinde olacak.
Menüden File/Save All tıklayın ve Menuden Build/Build Solutin tıklayın.
Microsoft Visual Studio.NET’ i indirin ve projenizin bulunduğu klasöre geçin
Bu klasörün içinde XPStyle.exe.manifest dosyasını göreceksiniz.
Bu dosyayı kopyalayıp, Obj klasörünün içine girin, buradan da Debug klasörüne tıklayıp içine girin ve dosyayı buraya yapıştırın.
Çalışma esnasında faydalanmak içi bu dosyayı bin\debug klasörüne de kopyalayabilirsiniz
Microsoft Visual Studio.NET’ i açın
Menüden, File/Open/File tıklayın.
Açılan pencerede Obj\Debug klasörüne ulaşın.
Buradan XPStyle çalıştırılabilir dosyanızı seçin ve Open butonuna tıklayın.
Açılan XPStyle.exe dosyasının içindeyken sağ tıklayın.
Açılan menuden Add Resource tıklayın.
Açılan pencereden import butonuna tıklayın.
Açılan pencreden Files of type alanında All Files seçin.
Görünen dosyalardan XPStyle.exe.manifest dosyasını seçip Open butonuna tıklayın.
Açılan Custom Resource Type penceresinde Resource Type alanına “RT_MANIFEST” yazın ve Okey butonuna tıklayın.
XPStyle.exe(101-Data) dosyası açıldı. Bu dosyadayken Properties penceresinden ID alanının 101 olan değerini 1 yapın
Menüden File/Save All tıklayın ve Menuden Build/Build Solutin tıklayın.
Bu dosyayı kapatın.
Projeyi çalıştırın.
Karşınızda aşağıdaki gibi XP stilli bir pencere göreceksiniz.
Yazıya Çevirme Örneği
Bu yazıda bir sayının yazıya nasıl çevirebileceğimiz hakkında bir yol göstereceğim, dil olarak C# kullanılacaktır. Öncelikle belirteyim ki programlama ve C# konusunda çok yeniyim. Hemen hemen tüm bildiklerimi bu siteye borçluyum.
Aşağıdaki kodda bulunan Oku fonksiyonu kendisine string olarak gönderilen tam sayıyı yazıya çevirmektedir. Kodun çalışma mantığı şöyledir.
oku fonksiyonuna gönderilen string başına “0” eklemek suretiyle önce 15 haneye tamamlanır, sonra yeni string 3 erli kümeler halinde 5 eşit parçaya bölünür ve her bir üçlü küme tek tek
rakam dizisine yüklenir. Böylece 5 elemanlı rakam dizisinin her bir elemanında 3 karakterli bir string yüklü olur.
1.Aşama
sayımız 32313234 olsun. ilk olarak sayımızın hane sayısını başına 0 eklemek sureti ile 15 e çıkarırız.
Böylece yeni stringimiz 000000032313234 şeklini alır.
2.Aşama
Stringimiz 3 erli kümeler halinde 5 eşit parçaya bölünür.
1. küme : 000
2. küme : 000
3. küme : 032
4. küme : 313
5. küme : 234
3.aşama
her bir küme 5 elemanlı rakam isimli araya yüklenir ve sonuçta
rakam[0] = “000”
rakam[5] = “234”
olur
rakam[5][0]=”2″ 5. kümenin yüzler basamağı;
rakam[5][1]= “3” 5. kümenin onlar basamağı;
rakam[5][2]= “4” 5. kümenin birler basamağı;
olur.
4.aşama
10 elemanlı yüzler, onlar, birler string dizileri tanımlanır ve i çleri doldurulur.
örn:
yuzler.SetValue(“ikiyuz”,2);
onlar.SetValue(“otuz”,3);
birler.SetValue(“dört”,4);
yani yuzler[2]+onlar[3]+birler[4] = ikiyüzotuzdört olur.
int x =Convert.ToInt16(rakam[5][0].ToString()); yüzler
int y =Convert.ToInt16(rakam[5][1].ToString()); onlar
int z =Convert.ToInt16(rakam[5][2].ToString()); birler
yuzler[x]+onlar[y]+birler[z] = ikiyüzotuzdört
bir döngü ile her bir kümeye bu işlemi uygularsanız, 1 ve ikinci kümlerin bütün elemanları sıfır olduğu için sonuçta
otuzdört
üçyüzonuç
ikiyüzotuzdört
ü elde edersiniz
5.Aşama
hane isimli 5 li array tanımlanır ve elemanları trilyon, milyar, milyon, bin ve sonuncusu da boş olacak şekilde ayarlanır. aynı döngü içerisinde her bir kümenin sonuna eklenir
string sonuc = “”;
for(int i = 0 ; i < 5;i++)
{
sonuc = sonuc +
yuzler[Convert.ToInt16(rakam[i][0].ToString())]+
onlar[Convert.ToInt16(rakam[i][1].ToString())]+
birler[Convert.ToInt16(rakam[i][2].ToString())]+
hane[i];
}
Burada ayarlanması gereken durum eğer bir kümenin bütün elemanları sıfırsa (yukarıdaki gibi) hanenin gözükmemesi gerekir. Yani
000 = yuzler[0]+onlar[0]+birler[0]+hane[0] dersek sonuç trilyon olur bu durumda
if(rakam[0].ToString()!= “000”)
hane.SetValue(“trilyon “,0);
if(rakam[1].ToString()!= “000”)
hane.SetValue(“milyar “,1);
if(rakam[2].ToString()!= “000”)
hane.SetValue(“milyon “,2);
if(rakam[3].ToString()!= “000”)
hane.SetValue(“bin “,3);
yani rakam[0] (trilyon kümesi) “000” değilse hane[0] = “trilyon” olsun demeliyiz.
Yanlız bir sorun daha var. eğer sayı 1000 ise fonksiyon bize haklı olarak “birbin” i döndürür. Bir milyar var, Bir Milyon var ama bir bin ve bir yüz yok. Ben bu sorunu BirSorunu isimli fonksiyonla hallettim.
Aşağıdaki kodu inceleyebilirsiniz.
| using System;
namespace numbereader { privatestring[ ] yuzler =newstring[10]; public SayiOkuma() { // içlerini dolduruyoruz yuzler.SetValue(“dokuzyüz”,9); onlar.SetValue(“doksan”,9); birler.SetValue(“dokuz”,9); hane.SetValue(“”,0); } public string oku(string sayi) { int uzunluk = sayi.Length; return “Hata girilen değerin uzunluğu en fazla 15 olmalı”; try long k = Convert.ToInt64(sayi); } catch(Exception ex) { return ex.Message.ToString(); } sayi = “000000000000000”+sayi; rakam.SetValue(sayi.Substring(0,3),0); if(rakam[0].ToString()!= “000”) string sonuc = “”; for(int i = 0 ; i < 5;i++) { sonuc = sonuc + yuzler[Convert.ToInt16(rakam[i][0].ToString())]+ } return sonuc; } privatestring birsorunu (string sorun) { string cozum = “”; else return cozum; } } } |
Herkese kolay gelsin. Bu arada dileyene DLL i gönderebilirim. İyi çalışmalar.
Temsilci (Delegate)ve Olay(Event) Kullanımı
Bu yazımda sizlere C#’ta delegate(delege veya elçi) ve event(olay) kavramlarından bahsedeceğim ve elbette bunları kullanmanın yararlarını anlatacağım. Kuşkusuz .Net Framework ile birlikte gelen en büyük yeniliklerden biri delege ve event kullanımıdır. Bu yanı ile .Net Framework diğer uygulama geliştirme ortamlarının bir kısmından daha üstün niteliklere sahip olmaktadır. Şimdi delege nedir biraz ondan bahsedelim. Delege basit anlamda düşünürsek aracılık yapandır. Burada ise delege aracılık yapan metod olarak karşımıza çıkar. Yani başka bir metodun tetiklenmesine yardım eden metottur. Bu sayede metodların tetiklenmesi dinamik olarak gerçekleşir. Olay(event) ise her zaman –belki farkında olmadan– kullandığımız kontroller gibidir. Yalnız delege ile olay arasındaki fark delegelerin “invoke” edilmesi olayların ise “raise” edilmesidir. Daha basit olarak ifade edersek olaylar delegelerin özel bir halidir. Delegeler olmadan olayların bir anlamı yoktur. Aslında bir örnekle bunların nasıl kullanıldığını açıklarsam daha iyi anlaşılacaktır. Şimdi çayın kaynamasını düşünün. Çay kaynadığı anda haberdar olmak istiyoruz ancak çayın başında da beklemek istemiyoruz. Bu yüzden bizi haberdar edecek zil çalma metodunu çayın kaynama metoduna bağlıyoruz. Ve çay kaynadığı anda zil çalma metodu da otomatik olarak tetiklenmiş oluyor. Delege ile olayın implementasyonunu aşağıda göstereceğim ve bunlarla ilgili bir program de koyarak anlaşılmasını kolaylaştıracağım. Çünkü bazen programlarla anlatmak istediklerimizi daha iyi anlatırız.
I. Olayın(event) yapılışı: Mouse’ın tıklanması, form üzerindeki bir tuşa basılması, form üzerindeki bir linkin tıklanması vs… bunların hepsi birer olaydır aslında. Şimdi mouse tıklanması ile ilgili bir kodu inceleyelim:
private void FareTikla()
{
// Buraya mouse’un sol tıklanması durumunda yapılması gereken
// işlemler gelecek.
}
// Burada fareye sol tıklandığı zaman çalışacak olan metodu bağlıyoruz. Bu işlemi de doğal olarak delegelerle yapıyoruz. Buradaki ‘+=’ operatörüne dikkat ettiniz mi? Bu ‘+=’ operatörü fareye sol tıklanması olayı karşısında raise edilecek eventi bağlamamıza yarıyor.
Mouse.MouseClicked += new MouseClickedEventHandler(FareTikla);
// Şimdi de fare sol tıklandığı zaman çalışacak olan metodu devreden çıkarıyoruz. Bu sayede fare sol tıklandığı zaman hiç bir metot //devreye girmeyecektir. Yani farenin sol tıklanmasına herhangi bir tepki verilmeyecektir.
Mouse.MouseClicked -= new MouseClickedEventHandler(FareTikla);
II. Delegenin yapılışı: Delege kullanılacağı zaman tek başına da kullanılabildiği gibi olaylara bağlanarak da kullanılabilmektedir. Bu yüzden ilk önce olayı(event) anlarsak delegenin anlaşılması daha da kolaylaşacaktır. Şimdi basit bir delege nasıl tanımlanır ona bakalım.
// Tanımladığımız delege double tipinde parametre alıyor
// ve int tipinde değer döndürüyor.
public delegate int myDelegate(double D);
// Delegenin temsil edeceği metodu yazalım.
public int ReturnInt(double D)
{
//Buraya metod çalışınca yapılması gerekecek olan kod gelecek
}
// Şimdi de delegenin bir örneğini yaratalım.
public void amethod(
{
myDelegate aDelegate = new myDelegate(ReturnInt);
}
//Şimdi de delegenin temsil ettiği metodun nasıl çalıştırılacağını sağlayan kodu yazalım.
aDelegate(3333);
Şimdi bu delege ve olay yapısı bizim ne işimize yarayacak derseniz; Şöyle bir senaryo üretelim: Birden fazla formda aynı anda çalıştığımızı ve bu formların da birbirinin aynı olduğunu düşünelim(şekilsel olarak tabii ki) ve bu formlardan herhangi birinin üzerindeki bir tuşa basıldığı zaman bütün formlarda hangi formun tıklandığına dair bir yazı yazmasını isteyelim.
Bunu eğer uzun yoldan yapmak isterseniz tek tek bütün formlar içinde birer tane değişken tanımlayıp onu kontrol etmeniz gerekirdi. Sonra da tek tek diğer formlara mesaj gönderilmesini sağlamak gerekirdi. Bu şekilde yapmak uzun ve zahmetli bir iş olurdu.
İkinci yöntem ise delege(temsilci) yapısını kullanmaktır. Şimdi her formumuz için bir tane forma mesaj yazacak olan bir metod olmalı ve bu metod hangi formdaki yazdırma tuşunun tetiklendiğini belirtmek için bir tane de parametre almalı. Şimdi de yukarıda anlattığımız senaryonun kodunu inceleyelim.
Ana formumuz içinde tanımladığımız delege ve olay yapısına bakalım. Burada delegemiz tamsayı(int) bir parametre alıyor. Bu parametre sayesinde hangi formdaki tuşa basılarak bu delegenin harekete geçirildiğini anlayabileceğiz. Olayımıza bakacak olursak olayımızın bir üst satırda tanımlanan delege tipinde olduğunu görebiliriz.
sayac değişkeni ise forma numara vermek için tanımlanmış bir değişken oluyor.
private int sayac = 0;
public delegate void userDelegate(int formNo);
public event userDelegate userEvent;
Yeni form oluşturma tuşuna basılınca ise yeni form oluşturulacak ve bu formun içindeki etikete yazma metodu olaya eklenecek.
sayac = sayac+1;
FrmUser frmUser=new FrmUser(sayac,this);
this.userEvent += new userDelegate(frmUser.writeFormNo);
Olaylara doğrudan başka sınıflar altından erişilebilse de bu yöntem pek doğru bir yol olmayacağı için olayımızı bir metodun içinde kamufle ederek kullanıyoruz. O yüzden olayımızı metodTetikle adında bir metodun içinde kamufle ederek kullanıyoruz. Başka bir formdan içinden bu metod çağrıldığı an otomatik olarak olayımızı tetikleyip bütün formlara(ana formumuz hariç) hangi formdan tuşa baıldığını yazacak.
public void metodTetikle(int formNo)
{
userEvent(formNo);
}
Bir de şimdi olaydan belli bir delegenin çıkarılması işlemi var değil mi? Öyle ya yaratılan formlardan bir tanesi kapatılırsa yazdırma metodunun tetiklenmesi istisna’ya (exception) yol açar. Bu yüzden bu formun metodunun listeden çıkarılması gerekir. Aşağıdaki kod bu işi yaparak bizi istenmeyen hatalardan korumuş olur.
public void elemanCikart(FrmUser frmUser)
{
this.userEvent -= new userDelegate(frmUser.writeFormNo);
}
Yukarıdaki kodun tamamı ana formumuz içinde yer alan kodlardı. Şimdi de ana formda tuşa basılınca oluşturulan formun içinde koda bakalım.
Formlara yazı yazdırmak için tuşa bastığımızda ana formumuzdaki metodTetikle metodunu çağırarak olayın tetiklenmesini sağlıyoruz.
private void btnActive_Click(object sender, System.EventArgs e)
{
form1.metodTetikle(formNo);
}
Ancak her formun içinde forma mesajı yazacak olan kısım aşağıdaki metoddakigibidir. Şimdi diyeceksiniz, niye aynı form içindeki metodu başka bir formu kullanarak çağırıyorsunuz. Ama buradaki fark ekrana mesaj yazacak olan form sayısının bir tane olmamasıdır. N tane forma aynı anda mesaj yazdırmak istediğimiz için bir başka sınıfta veya formda tanımlanmış olan bir olayı tetikleyerek bu işi yapıyoruz. Aksi halde N tane formu tek tek dolaşmamız gerekirdi. Bu ise performans kaybına yol açtığı gibi daha büyük programlarda kod karmaşasına yol açabilmektedir.
public void writeFormNo(int tetiklenenNo)
{
lblAciklama.Text=”Tuşa Basılan Form Numarası:”+tetiklenenNo;
}
Galiba bir tek sonradan oluşturulmuş bir form kapatılınca ana formumuzdaki delege çıkartma metodunun nasıl çağrılacağı kaldı. Onu da sonradan oluşturulan formumuzun Dispose metodu içine aşağıdaki gibi yazarsak hiç bir şekilde hatayla karşılaşmayız.
form1.elemanCikart(this);
Evet yukarıda delege ve olayın nasıl bir arada kullanıldığını basit bir örnek üzerinde anlatmış oldum. Yukarıda delege ve olayın bir arada kullanıldığı örnek programı buraya tıklayarak indirebilirsiniz.
Son olarak iyi anlayamadığınız veya kafanıza takılan kısımlar için mail adresim aytacozay@msakademik.net
