28 Temmuz 2011 Perşembe

C#'da Settings Kullanımı

Özet :
Uygulamalarımızda kullanıcı bazında veya uygulama bazında ayarlar yapmak için Settings class'ını kullanabiliriz. Settings class'ı ile uygulamayı kullanacak olan kişilere uygulamanın bazı özelliklerini kendilerinin belirleyecekleri şekilde kullanmalarına olanak sağlayabilir veya uygulamanın çalışması için gerekli olan bazı değerleri Settings içinde tutarak uygulamadan bu değerlere erişebiliriz.

Merhabalar,

Uygulamalarımızda kullanıcı bazında veya uygulama bazında ayarlar yapmak için Settings class'ını kullanabiliriz. Settings class'ı ile uygulamayı kullanacak olan kişilere uygulamanın bazı özelliklerini kendilerinin belirleyecekleri şekilde kullanmalarına olanak sağlayabilir veya uygulamanın çalışması için gerekli olan bazı değerleri Settings içinde tutarak uygulamadan bu değerlere erişebiliriz. Settings class'ı C#'da Properties namespace'i aldında bulunur ve dört önemli property'e sahiptir. Bunlardan birincisi Name property'sidir. Name property'si uygulamada tutulacak olan ayarın adının belirlendiği ve ilgili ayara değer atarken erişilmesine olanak sağlayan property'dir. İkinci property olan Type ise ayarın alacağı değerin tipinin tutulduğu property'dir. Örneğin string, boolean veya Color. Scope property'si ise User veya Application değerlerinden birini alır. Bir ayarın Scope'ı Application olarak set edilmişse bu ayar uygulamada kullanıcı tercihlerine bağlı olarak kullanıcı tarafından değiştirilemeyen, uygulamanın çalışmasını önemli derecede etkileyen ayardır. Örneğin uygulamanın veritabanının connection string'i. User scope'lı ayarlar ise kullanıcı bazında değişebilen ve uygulamanın çalışması açısından o kadar da önemli olmayan ayarlardır. Örneğin uygulamadaki butonların rengi gibi. Bu iki değer arasında önemli olan bir fark daha bulunmaktadır. User scope'lı ayarlar uygulama çalışırken erişilebilir ve yeniden ayarlanabilir özelliğe sahipken, Application scope'lı ayarlar uygulama çalışırken read-only'dirler. Application scope'lı ayarları sadece designer ekranından veya .settings dosyasını elle değiştirerek değiştirebilirsiniz.

Şimdi örnek bir uygulamada Settings class'ının kullanımını inceleyelim. Uygulamamızda Settings class'ı yardımıyla form text'i, arkaplan rengi gibi bazı ayarları nasıl oluşturabileceğimizi inceleyeceğiz. İlk olarak yeni bir Windows uygulaması oluşturalım. Oluşturduğumuz uygulamada set edeceğimiz ayarlar aşağıdaki gibi olacak:
- Form text'i
- Form arkaplan rengi
- Uygulamanın açılış sesi
- Formun maximize edilip edilemeyeceği

Bu ayarların hepsine bir ad, alacağı değerin tipi ve ayarın scope'ını belirleyeceğimiz .settings dosyasını açıyoruz ve yukarıda belirtilen öğeleri designer ekranından giriyoruz:


Uygulamamız açılırken çalmasını istediğimiz .wav dosyasının lokasyonunu string tipinde AcilisSesi property'sinde tutacağız. Formun arkaplan rengini Color tipinde FormArkaplanRenk property'sinde, text'ini FormText property'sinde tutacağız. Son olarak formun maximize edilip edilemeyeceğini de boolean tipinde MaximizeEnabled property'sinde tutacağız. Bütün property'lerin Scope'larını User olarak belirleyip Value'larını boş bırakalım.
Sıra uygulamamızın ekranlarını tasarlamaya geldi. Uygulamamızda iki adet form olacak, bunlardan birincisi set edilmiş ayarların gösterileceği ana ekran ve diğeri de ayarları set edebileceğimiz ayarlar ekranı olacak. Ana ekranı aşağıdaki gibi tasarlayalım:


Bu formdaki MenuStrip öğelerinden Ayarlar'a tıklandığında ayarlar ekranı açılacak, Ayarları Yükle'ye basıldığında ise ayarlar ekranında set edilmiş olan ayarların güncel hali yüklenecek. Ayarları yapacağımız ikinci ekranı ise aşağıdaki gibi tasarlayalım:

Şimdi ilk olarak Ayarlar ekranının kodunu yazmaya başlayalım. Arkaplan rengini belirlemek için formumuza bir ColorDialog kontrolü ekliyoruz ve Arkaplan Rengi label'ının hizasında olan butonun click event'ine aşağıdaki kodu yazıyoruz:

private void btnOpenColorDialog_Click(object sender, EventArgs e)
{
colorDialog1.ShowDialog();
lblArkaplanDeger.BackColor = colorDialog1.Color;
}

Butonun click event'inde color dialog'u açıyor ve seçilen rengi fomdaki label'ın arkaplan rengi property'sine atıyoruz. Sırada uygulama açıldığı zaman çalacak olan .wav dosyasının belirlenmesi var. Bunun için de formumuza Açılış Sesi label'ının hizasında olan butona tıklandığında açılacak olan bir OpenFileDialog nesnesi ekliyoruz ve butonun Click event'ine aşağıdaki kodu yazıyoruz:

private void btnPickAcilisSesi_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
lblAcilisSesiDeger.Text = openFileDialog1.FileName.Substring(openFileDialog1.FileName.LastIndexOf(@"\") + 1);
lblAcilisSesiDeger.Tag = openFileDialog1.FileName;
}

Ayarlara atanacak değerler için yazmamız gereken başka bir kod kalmadığına göre artık ayarları kaydetme aşamasına gelebiliriz. Kaydet butonunun click event'ine aşağıdaki kodu yazıyoruz:

private void btnKaydet_Click(object sender, EventArgs e)
{
Settings.Default.AcilisSesi = lblAcilisSesiDeger.Tag.ToString();
Settings.Default.FormArkaplanRenk = lblArkaplanDeger.BackColor;
Settings.Default.FormText = txtFormTextDeger.Text;
Settings.Default.MaximizeEnabled = chkMaximizeEnabled.Checked;
Settings.Default.Save();
this.Close();
}

Butonun click event'inde tek yapmamız gereken bu property'lere formun üstündeki kontrollerin değerlerini atamak. AcilisSesi property'sine label'ın tag'ına atadığımız değeri, FormArkaplanRenk property'sine lblArkaplanDeger label'ının BackColor property'sinin değerini, FormText property'sine textbox'da yazan yazıyı ve MaximizeEnabled property'sine de checkbox'ın değerini atıyoruz. Ardından da Settings nesnesinin Save metodunu çağırarak ayarları kaydediyoruz ve Ayarlar formunu kapatıyoruz.

Son olarak Ayarlar formu yüklendiği zaman mevcut ayarların görüntülenmesi için formun Load'ına aşağıdaki kodu yazalım:

private void frmAyarlar_Load(object sender, EventArgs e)
{
lblAcilisSesiDeger.Text = Settings.Default.AcilisSesi.Substring(Settings.Default.AcilisSesi.LastIndexOf(@"\") + 1);
lblAcilisSesiDeger.Tag = Settings.Default.AcilisSesi;
lblArkaplanDeger.BackColor = Settings.Default.FormArkaplanRenk;
txtFormTextDeger.Text = Settings.Default.FormText;
chkMaximizeEnabled.Checked = Settings.Default.MaximizeEnabled;
}

Yukarıda görüldüğü gibi biraz önceki işlemin tam tersini yapıyoruz ve form üstündeki kontrollere mevcut ayarların değerlerini atıyoruz. Ayarlar ekranında yazmamız gereken kodlar bunlardan ibaret. Şimdi uygulamanın ana ekranına geçelim. Bu ekran yüklenirken yani uygulama başlatıldığında formun yüklenmiş ayarlarla beraber açılması gerekiyor. Bu yüzden formun Load'ında settings dosyasından alınan değerleri formun text'ine, arkaplanına vs atayacağız:

private void Form1_Load(object sender, EventArgs e)
{
SoundPlayer sp = new SoundPlayer();
sp.SoundLocation = Settings.Default.AcilisSesi;
sp.Play();
this.BackColor = Settings.Default.FormArkaplanRenk;
this.Text = Settings.Default.FormText;
this.MaximizeBox = Settings.Default.MaximizeEnabled;
}

Settings'de tutulan property'lerin değerlerini okuyarak form açılırken AcilisSesi property'sinde belirlenmiş olan .wav dosyasının çalınmasını, FormArkaplanRenk property'sinde belirlenmiş olan rengin arkaplan rengi olarak atanmasını, FormText property'sinde belirlenmiş olan yazının formun text'ine atanmasını ve MaximizeEnabled property'sindeki değere bağlı olarak da formun maximize edilip edilemeyeceğini sağlamış olduk. Şimdi formdaki iki menustrip öğesine tıklandığında çalışacak olan kodu yazalım:

private void ayarlarToolStripMenuItem_Click(object sender, EventArgs e)
{
frmAyarlar f = new frmAyarlar();
f.ShowDialog();
}

private void ayarlarıYükleToolStripMenuItem_Click(object sender, EventArgs e)
{
this.BackColor = Settings.Default.FormArkaplanRenk;
this.Text = Settings.Default.FormText;
this.MaximizeBox = Settings.Default.MaximizeEnabled;
}

Ayarlar'a tıklandığında Ayarlar ekranı açılacak ve Ayarları Yükle'ye tıklandığında ise Settings nesnesinde tutulan ayarlar form'un property'lerine tekrar yüklenecek ve ekran en güncel haliyle görüntülenecek. Uygulamamızı çalıştırıp ayarları aşağıda görüldüğü gibi set edelim:


Kaydet butonuna basıp ayarları kaydedelim ve ana ekranda Ayarları Yükle'ye basalım. Formun arkaplan rengi, text'i ve maximize butonu bizim belirlediğimiz şekilde yüklenecektir:

Uygulamayı kapatıp yeniden çalıştırdığımızda ise açılışta çalmasını istediğimiz .wav dosyası çalacaktır.

Bu makalemde Settings class'ı yardımıyla uygulamamızda ayar oluşturmaktan bahsettim. Faydalı olmasını umarım.

Işıl ORHANEL ' e teşekkürler.
Share:

27 Temmuz 2011 Çarşamba

C# Thread Kullanımı

C#’ta thread kullanımı aynı anda birden fazla iş yapmamızı sağlar.Bu şekilde programımızı birden fazla iş bölümüne ayrabiliriz.Farklı thradlar aynı fonksiyonu kullanabiliceği gibi farklı fonksiyonlarıda kullanabilirler.



Programımızda thread kullanmak için öncelikle threading kütüphanesini programımıza eklemeliyiz.

using System.Threading;

Sonrasında istediğimiz event içind threadlarımızı aşağıdaki gibi tanımlayıp başlatabiliriz

System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false;
Thread thread1 = new Thread(new ThreadStart(listBox1Ekle));
Thread thread2 = new Thread(new ThreadStart(listBox2Ekle));
Thread thread3 = new Thread(new ThreadStart(listBox3Ekle));

thread1.Start();
thread2.Start();
thread3.Start();


Yukarıda 3 tane thread tanımlanmıştır ve herbiri ayrı fonksiyonları çağırmaktadır.Eğer System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false; komutunu kullanmassak hata alırız bunun sebebi ise thread lerin senkronlanmadığından.Yukarıda çağırılan fonksiyonlarda aşağıdaki şekilde tanımlayalım.

private void listBox1Ekle()
{
for (int i = 0; i < 100; i++)
{
listBox1.Items.Add(i + "-Thread1");
Thread.Sleep(300);
}

}

private void listBox2Ekle()
{
for (int i = 0; i < 100; i++)
{
listBox2.Items.Add(i + "-Thread2");
Thread.Sleep(500);
}
}

private void listBox3Ekle()
{
for (int i = 0; i < 100; i++)
{
listBox3.Items.Add(i + "-Thread3");
Thread.Sleep(700);
}
}

Programda görüldüğü gibi 3 ayrı thread farklı zaman dilimlerinde listboxları dolduracatır.Thread kullanımı kısaca bu mantıkta çalışır.
Share:

C# ile Clipboard İşlemleri

Merhabalar,

Clipboard hepimizin hergün birçok kere yazı, resim, dosya kopyalayıp yapıştırmak için kullandığımız bir araç. Ben bu makalemde ilk olarak .NET'te Clipboard class'ını kullanarak clipboard'a veri kopyalama ve kopyalanmış olan veriyi okumanın nasıl yapılabileceğini basit bir örnek üzerinden anlatacağım. Ardından ise Win32 fonksiyonları ile bize sunulan Clipboard API'sini kullanarak panoya kopyalanmış olan yazıların görüntülendiği bir uygulama yapacağım.

İlk olarak Clipboard'da tutulan yazı veya resmi uygulama üstündeki textbox veya picturebox'a yapıştırabileceğimiz ve textbox veya picturebox'daki resmi/yazıyı Clipboard'a kopyalayabileceğimiz uygulamamızı yazalım. Bir Windows uygulaması oluşturup formu aşağıdaki gibi tasarlayalım:


private void btnYaziyiKopyala_Click(object sender, EventArgs e)
{
Clipboard.SetDataObject(txtYapistir.SelectedText, true);
}

private void btnYaziyiYapistir_Click(object sender, EventArgs e)
{
IDataObject dObj = Clipboard.GetDataObject();
if (dObj.GetDataPresent(DataFormats.Text))
{
txtYapistir.Text = dObj.GetData(DataFormats.Text).ToString();
}
}
Görüldüğü gibi Clipboard nesnesinin iki tane önemli öğesi bulunmakta. Bunlardan birincisi olan SetDataObject metodu Clipboard'a veri eklemek için kullanılır. Bu metodun iki tane overload'ı vardır. Birinci overload'ı parametre olarak sadece object tipinde veri alır. Bu Clipboard'a kopyalanacak olan verinin tutulduğu parametredir. Diğer overload'ında ise object parametresinin yanısıra boolean tipinde bir parametre daha vardır. Bu parametrenin değerini true olarak set ettiğimizde uygulama sonlandığı zaman uygulamadan kopyalanmış olan verilerin Clipboard'dan silinmeden tutulmasını sağlarız. Böylece diğer uygulamalar da Clipboard'a kopyalanmış olan bu veriye erişebilirler. Bu parametreyi false olarak set ettiğimizde uygulama sonlanınca uygulama tarafından Clipboard'a kopyalanmış olan veriler de Clipboard'dan silinecektir. Biz kendi uygulamamızda bu parametreyi true olarak set ettik.

Clipboard'ın ikinci önemli öğesi olan GetDataObject fonksiyonu da Clipboard'da tutulmakta olan veriye erişebilmemizi sağlar. Bu fonksiyon IDataObject nesnesi döndürür. Fonksiyondan dönen IDataObject nesnesinin GetDataPresent fonksiyonunu kullanarak Clipboard'da tutulan verinin bizim istediğimiz tipte veri olup olmadığını anlayabiliriz. Biz bu örnekte dönen verinin tipi Text ise formumuzdaki textbox'ın Text property'sine yine IDataObject nesnesinin GetData fonksiyonunu kullanarak Clipboard'dan aldığımız veriyi atadık.

Şimdi de yine benzer şekilde Clipboard'da duran bir resmi formumuz üstündeki picturebox'a atayalım ve formumuzdaki picturebox'da duran resmi Clipboard'a yapıştıralım. Bunun için Resmi Kopyala ve Resmi Yapıştır butonlarının Click eventlerine aşağıdaki kodu yazıyoruz:

private void btnResmiKopyala_Click(object sender, EventArgs e)
{
Clipboard.SetDataObject(pbxResim.Image, true);
}

private void btnResmiYapistir_Click(object sender, EventArgs e)
{
IDataObject dObj = Clipboard.GetDataObject();
if (dObj.GetDataPresent(DataFormats.Bitmap))
{
pbxResim.Image = (Bitmap)dObj.GetData(DataFormats.Bitmap);
pbxResim.SizeMode = PictureBoxSizeMode.StretchImage;
}
}

Görüldüğü gibi bu örneği bir önceki örnekte yazdığımız kodla aynı mantıkta yazdık. Tek fark Clipboard'ın SetDataObject metodunda Text yerine Image nesnesini gönderdik ve veriyi Clipboard'dan da okurken IDataObject nesnesinin GetDataPresent ve GetData fonksiyonlarında DataFormats enum'unun Bitmap öğesini parametre olarak gönderdik. Son olarak da formumuz üstündeki picturebox'ın SizeMode property'sini resmin tamamı picturebox'a sığsın diye StretchImage olarak set ettik.

Uygulamamızda yazacağımız kodları tamamladık, artık çalıştırabiliriz:


İlk olarak notepad'den kopyaladığım yazıyı uygulamadaki textbox'a Yazıyı Yapıştır butonuna tıklayarak yapıştırdım. Form üstündeki textbox'a birşeyler yazıp Yazıyı Kopyala butonuna basınca da text Clipboard'a kopyalanacaktır. Şimdi de paint'te bir resmi kopyalayıp form üstündeki picturebox'a yapıştıralım:

Görüldüğü gibi .NET tarafından bize sunulan Clipboard class'ı ile uygulamamız üzerinden kopyalama-yapıştırma işlemlerini idare etmek oldukça kolay bir işlem. Şimdi sırada API yardımıyla Clipboard işlemlerini yapacağımız formumuzu geliştirmek var. Bu formumuz Clipboard'ı dinleyecek ve Clipboard'a bir yazı kopyalandığında formumuz üstündeki textbox'a yazıyı yapıştıracak. İlk olarak basitçe formumuzu aşağıdaki gibi tasarlayalım:

Bu işlemi gerçekleştirmek için de Win32'nin Clipboard işlemleri için sunduğu SetClipboardViewer, ChangeClipboardChain, SendMessage fonksiyonlarını kullanacağız. Bu fonksiyonları .NET ortamından çağırmak için de DllImport attribute'ını kullanarak fonksiyonları import edeceğiz:
...

using System.Runtime.InteropServices;

namespace ClipboardMakale
{
public partial class Form2 : Form
{
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SetClipboardViewer(IntPtr hWnd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
...

Ardından ise Clipboard'da tutulan verinin saklanacağı class level bir pointer tanımlayalım:

IntPtr SonrakiClipboardOgesi;

Sonrasında ise formun load'ında SetClipboardViewer fonksiyonunu çağırıyoruz. Bu fonksiyon uygulamamızı Clipboard'ı izleyen uygulamaların listesine ekleyecek:

private void Form2_Load(object sender, EventArgs e)
{
SonrakiClipboardOgesi = SetClipboardViewer(this.Handle);
}

Şimdi ise sırada WndProc metodunu override etmek var:

protected override void WndProc(ref Message m)
{
int WM_DRAWCLIPBOARD = 0x0308;
int WM_CHANGECBCHAIN = 0x030D;

if (m.Msg == WM_DRAWCLIPBOARD)
{
ClipboardOku();
SendMessage(SonrakiClipboardOgesi, m.Msg, m.WParam, m.LParam);
}
else if (m.Msg == WM_CHANGECBCHAIN)
{
if (m.WParam == SonrakiClipboardOgesi)
{
SonrakiClipboardOgesi = m.LParam;
}
else
{
SendMessage(SonrakiClipboardOgesi, m.Msg, m.WParam, m.LParam);
}
}

base.WndProc(ref m);
}

private void ClipboardOku()
{
IDataObject dObj = Clipboard.GetDataObject();
if (dObj.GetDataPresent(DataFormats.Text))
{
textBox1.Text = (string)dObj.GetData(DataFormats.Text);
}
}

Windows, Clipboard'da tutulan veriler değiştiği zamanlarda verinin değiştiğine dair bildirimde bulunulacak olan pencerelerin bir listesini tutar. Ve WM_DRAWCLIPBOARD mesajı da clipboard içeriğini görüntüleyen ilk pencereye gönderilir. Bu, clipboard'ın içeriğini görüntüleyen pencerenin clipboard'daki en güncel içeriği elde etmesini sağlar. Bu içeriği sadece Clipboard içeriği görüntülemeye yetkili olan pencereler elde edebilirler. Biz zaten formumuz yüklenirken SetClipboardViewer fonksiyonunu çağırarak uygulamamıza clipboard içeriğini alabilme yetisini kazandırmıştık. Şimdi de WM_DRAWCLIPBOARD mesajını handle ederek Clipboard içeriğini elde edebiliriz. Kodda görüldüğü üzere pencereye WM_DRAWCLIPBOARD mesajı geldiğinde ilk olarak ClipboardOku metodunda gelen veriyi (Text ise) textbox'a yazdırıyoruz ve ardından SendMessage metodu ile de Clipboard'ı izleyen diğer pencerelere de Clipboard'daki bu değişikliğin yansımasını sağlıyoruz.

Handle etmemiz gerekecek olan diğer mesaj da WM_CHANGECBCHAIN olacak. Bu mesaj Clipboard'ı izleyen uygulamalardan birisi ortadan kalktığında Clipboard'ı izleyen uygulamalardan ilkine gönderilir. Eğer uygulamamıza WM_CHANGECBCHAIN mesajı gelirse, uygulamamız SendMessage fonksiyonunu kullanarak bu mesajı Clipboard'ı izleyen sıradaki uygulamaya gönderecek. Eğer sıradaki uygulama zincirden kaldırılacak olan uygulama ise SonrakiClipboardOgesi zincirden kaldırılacak olan uygulamadan sonraki ilk uygulamaya atanacak.

Son olarak bizim uygulamamız sonlanırken yani formun FormClosing event'inde ChangeClipboardChain fonksiyonunu çağırarak uygulamamızı Clipboard'ı izleyen uygulamaların listesinden çıkarıyoruz:

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
ChangeClipboardChain(this.Handle, SonrakiClipboardOgesi);
}
Bu noktadan sonra artık uygulamamız Clipboard'daki değişiklikleri izleyebilecek ve Clipboard'daki herhangi bir değişiklik anında uygulamamıza yansıyacaktır. Örneğin uygulamamızı çalıştırıp notepad'den yazı kopyaladığımızda uygulamamızdaki textbox'da da kopyaladığımız yazıyı görebiliriz. Bu bilgiler ışığında dilerseniz siz de Office uygulamalarında olduğu gibi bilgisayarınızda çalışırken kopyaladığınız metinleri, resimleri saklayıp sonradan kullanabileceğiniz küçük bir uygulama yazabilirsiniz.

Alıntı : Işıl ORHANEL ' bu güzel makalesinden dolayı teşekkürler.
Share:

Blog Arşivi