Yaptığımız programı farklı ülkelerdeki insanlarında kullanmasını isteyebiliriz. Bu özellik birçok programlarda mevcut, biz bunun istersek programımızda geniş bir matris dizisi tanımlayarak yapabileceğimiz gibi Visual Studio IDE’sinin bize sunduğu ‘Resource File’ ile de yapabiliriz. Bunun için önce projemize bir ‘Resource File’ ekleyelim. Bunun için;
– Project->Add New Item->General->Resource File->DilAyari.tr-TR.resx ve DilAyari.en-US.resx isimlerinde 2tane resource file ekleyelim.
Burada dikkat edilmesi gereken nokta tr-TR dememiz. Bu kod Ingilizce için en-US, Italyanca için it-IT olarak değiştirilebilir. Tam liste için MSDN’e başvurabilirsiniz. .resX uzantılı dosyalarını açtığımız zaman karşımıza Excel tablosu gibi bir tablo çıkacaktır. Burada 3 tane sütun var; -Isim, -Değer, -Yorum. Projemizde bir tane buton olsun ve bu butonun ismide ‘Tamam’ olsun, eğer kullanıcı programı ingilizce kullanmak istiyorsa bunu ‘OK’ olarak görsün. Bunun için şimdi eklediğimiz DilAyari.tr-TR.resx dosyasını açalım ve şu şekilde dolduralım
Name = ‘tmm_btn’, Value = ‘Tamam’
DilAyari.en-US.resx için;
Name = ‘tmm_btn’, Value = ‘OK’
2 dosyada da butonumuza isim verdik. Şimdi bunları kullanmaya geldi. Kullanıcı için 2 tane dil için buton ekleyelim.
private void turkce_btn_Click(object sender, EventArgs e)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("tr-TR");
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");button1.Text = resM.GetString("tmm_btn");
}
Bu kodu incelersek, önce programımızın çalışacağı dil için Thread sınıfının üyesi olan CurrentThread properties’inde bulunan CurrentUICultere ve CurrentCulture properties’i Türkçe olarak ayarlıyoruz. Ardından da butonumuzun ismini düzeltiyoruz. Burada resM’i aşağıdaki gibi tanımladım;
ResourceManager resM = new ResourceManager("WindowsProject1.DilAyari",
Assembly.GetExecutingAssembly()
);
Eğer programınız da birden fazla kontrol varsa bunları bir fonksiyon altında toplarsanız sizin için daha rahat olacaktır. O zaman tek yapmanız gereken ‘Türkçe’ butonuna basıldığı zaman Cultere ayarlarını yapmak ve fonksiyonu çağırmak olacaktır. Bir avantajıda şu, mesela siz ileride bir tane daha buton eklediniz ya da başka birşey bunun dil ayarlarını yapmak için hem türkçe hem ingilizce ya da varsa diğer dillerin butonunun altına tek tek yazmak yerine sadece fonksiyona yazarsınız ve işlem tamamlanmış olur.
Bir ayın konusunun daha sonuna geldik, umarım sizler için faydalı olmuştur…
Birçok programda bu özellik mevcuttur, herkesin kullandığı MSN programında bile arkadaşlarımıza dosya göndereceğimiz zaman yazı yazdığımız yere dosyayı sürükleyip bırakırız. Peki biz bunu kendi programımıza nasıl ekleyeceğiz? Mesela formumuzda bir ‘TextBox’ olsa kullanıcı metin dosyasını ‘TextBox’a sürükleyip bıraktığında içindeki yazıları ‘TextBox’da göstersek, ya da en güzeli ana formumuza istediği dosyayı bıraksın biz belirleyelim nerede gözükeceğini :), resim ise ‘PictureBox’da metin dosyası ise ‘TextBox’da, excel dosyası ise ‘DataGrid’de vb. Nasıl olur? (En sonuncusu bence en güzeliydi).
Ilk olarak yapmamız gereken sürükle-bırak özelliğini kullanacağımız kontrol’ün ‘AllowDrop’ özelliğini ‘true’ yapmamız lazım. Bunu yaptığımız zaman kontrolün üzerine bir dosya sürüklediğimizde dosyanın bırakılabileceği anlamına gelen simgeye dönüşecek fare imleçimiz. (Not: ‘AllowDrop’ özelliği bazı kontrollerde mevcut değil. PictureBox, GroupBox vb.) Bu işlemi yaptıktan sonra sıra dosyayı bıraktıktan sonraki işlemleri yapmak kaldı. Bunun için kontrollerin iki tane ‘Event’i mevcut; ‘DragDrop’: Dosya bırakıldıktan sonra tetiklenen fonksiyon. ‘DragEnter’: Dosya bırakılmadan kontrolün üzerindeyken tetiklenen fonksiyon.
‘DragEnter’ ‘Event’inde dosya bırakıldı mı diye kontrol ediliyor eğer dosya bırakıldıysa, kontrolün ‘DragDrop’ ‘Event’i yapılıyor, burada yapılan işlemler, ben bütün bırakılan dosyalarla işlem yapmak istemediğim için sadece ilk dosyanın ismini aldım, eğer siz uygulamanızda birden fazla dosya bırakıldığı zaman hepsini kullanmak istiyorsanız ‘dosyalar’ isimli ‘string’ dizisini kullanabilirsiniz. Dosyanın ismini aldıktan sonra uzantısına baktım eğer metin dosyası formatlarından bir tanesi ise dosya ismini bir ‘TextBox’a yazdırdım, dosyayı okumak için FileStream sınıfı ile okuyup yazdırabilirsiniz. Gelelim son dediğimizi yapmaya; bu işlem için kod yazmayacağım zaten yukarıdaki koddan farklı birşey yapmayacaksınız. Sadece bunu ana formunuza uygulayacaksınız ve ‘DragDrop’ ‘Event’inde dosya formatına göre ayırarak ister bir ‘PictureBox’da gösterebileceksiniz, isterseniz ‘TextBox’da isterseniz ‘DataGrid’de tercih size kalmış. Hatta çoklu dosya bırakıldıysa bunları bir ‘ListBox’da gösterebilirsiniz.
Bir ayın konusunun daha sonuna geldik, umarım sizlere faydalı olur. Hepinize kolay gelsin, Iyi çalışamalar…
Arkadaşlar yeni bir Ayın Konusu ile sizlerleyim. Bu uygulama benim çok hoşuma gitmeye başladı çünkü burada duyurduklarımı yapma zorunluluğu hissediyorum ve eğer bunları yaparsam sitem sizler için daha faydalı olur diye ümit ediyorum. Bildiğiniz gibi ayın konularından biride ‘C# ile Toplu Mail Gönderme Programı ve Anlatımı’, konu başlığını okuyunca ‘Bunun neresi Ayın Konusu olmayı hak ediyor ki?’ diyebilirsiniz. Evet konu başlığına bakınca ‘mailMessage.To.Add(…)’ fonksiyonuna mailleri dizince gönderebilirim. Evet bu fonksiyonu kullanarak göndereceğiz. Ama bu bildiğimiz fonksiyonu kullanarak güzel bir program neden yapmıyoruz? Mesela kullanıcı mail hesapları tanımlasa!, Excel dosyasından veya metin belgesinden mail listesini eklese!, eklediği mailleri bir kişi listesi olarak kaydetse sonra tekrar seçebilse!. Bildiğimiz tek birşey var mailMessage.To.Add(…) fonksiyonu. Bu fonksiyondan yola çıkarak şimdi programımızı inceleyelim;
Programımızın yapabildikleri;
– Çoklu Mail hesabı tanımlama.
– Kişi listesi oluşturma imkanı.
– Excel dosyasındaki mail adreslerini okuyabilme.
– Oluşturduğu kişi listesini ve hesabı kaydebilme.
Ben programda bu bilgileri kaydetmek için XML dosyası kullandım, çok kararsız kaldım Access mi yoksa XML mi kullanayım diye ama sonra XML formatınıda bilmediğim için XML kullandım. Bu dosya formatını öğrenirken Burak Selim Şenyurt hocanın buradaki makalesi bana gerçekten çok yardımcı oldu. Öncelikle programın ‘Hesap Tanımla’ menüsünden bahsetmek istiyorum; Hesap tanımla işlemi için gerekli olan bilgileri kullanıcı ekrandan girmesini istiyoruz, bu bilgiler; -‘Hesap Adı’, -‘Mail Adresi’, -‘Şifresi’, -‘SMTP Server Adresi’, -‘Port Numarası’ ve -‘SSL’ bilgisi, bu bilgileri aldıktan sonra XML dosyamıza Hesap isimli boğum ile kaydediyoruz.
Birde ‘Hızlı Ayar’ kısmı var, burada eğer hotmail, gmail veya yahoo mail hesabını ekleyecekse ve kullanıcı smtp server adresini bilmiyorsa otomatik olarak yazılıyor. Hesap Ekle butonunda yapılacak görevler;
– Giriş Kontrol,
– Hesap Ekle,
– Girilen bilgileri temizle.
Bu işlemler yapıldıktan sonra kullanıcı artık bir mail hesabı tanımlamış oluyor, ana sayfadan mail göndereceği zaman istediği mail hesabını seçerek mailini gönderebilir.
İkinci menümüz ise tanımladığımız hesapları düzenleyecemiz menü;
Daha önceden tanımladığımız hesaplar üzerinde değişiklik yapabildiğimizi menü. Eğer mail adresimizin şifresini değiştirdiysek veya mail adresimizi yanlış yazdığımızı fark ettiysek bu menüden düzenleme yapabileceğiz. Ayrıca artık o mail hesabını kullanmıyorsak yine bu menüden hesabımızı silebiliyoruz. Sol tarafta ise eklemiş olduğumuz hesapları görebiliyoruz, buradan seçtiğimiz hesap bilgilerini sağ tarafta görebiliriz. Programda kullandığım 2 tane sınıf var bunlar; Hesap ve KisiListesi isminde bunları aşağıda detaylı bir biçimde açıklayacağım, birde bu ekleme-silme-güncelleme-bilgileri alma işlemleri için XmlYonetici sınıfı tanımladım bu sınıf Burak Selim Şenyurt hocanın kullandığı sınıfın bizim programımıza göre düzenlenmiş hali. Burak hocanın kullandığı yöntemden yola çıkarak güzel bir Xml veritabanı oluşturduk. İleride bu 3 sınıfı da detaylı bir şekilde anlatacağım;
Bir sonraki menümüz ise kişi listesini oluşturacağımız menü. Bu menüden kişi listemizi ister bir Excel tablosundan istersek dosyadan okuyabiliriz. Excel’den dosyaları okumak için ‘OleDbConnection’ sınıfından faydalandım. Burada takıldığım noktalardan biri mail adresleri hangi çalışma sayfasındaydı. Bu problemi kullanıcıya sorarak geçtim. Excel tablosundan ‘Ekle’ dediği zaman bir form çıkacak ve kullanıcıya maillerin hangi çalışma tablosunda olacağını soracaktı. Bu bilgiyide alarak aşağıdaki kod satırı ile Excel dosyasından mail adreslerini rahatlıkla aldım;
OleDbConnection baglanti =new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source= "+ openFile.FileName+";Extended Properties=Excel 8.0;");
baglanti.Open();string sorgu ="SELECT * FROM ["+ frm.tabloAdi+"$]";
OleDbDataAdapter data_adp =new OleDbDataAdapter(sorgu, baglanti);
DataTable mailTablo =new DataTable();
data_adp.Fill(mailTablo);int test = mailTablo.Columns[1].MaxLength;foreach(DataRow row in mailTablo.Rows){foreach(DataColumn column in mailTablo.Columns){if(row[column]!=System.DBNull.Value){if(mailAdresKontrol((string)row[column])){
mailList_lb.Items.Add((string)row[column]);}}}}
baglanti.Close();
OleDbConnection baglanti = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + openFile.FileName + ";Extended Properties=Excel 8.0;");
baglanti.Open();
string sorgu = "SELECT * FROM [" + frm.tabloAdi + "$]";
OleDbDataAdapter data_adp = new OleDbDataAdapter(sorgu, baglanti);
DataTable mailTablo = new DataTable();
data_adp.Fill(mailTablo);int test = mailTablo.Columns[1].MaxLength;foreach (DataRow row in mailTablo.Rows)
{
foreach (DataColumn column in mailTablo.Columns)
{
if (row[column] != System.DBNull.Value)
{
if (mailAdresKontrol((string)row[column]))
{
mailList_lb.Items.Add((string)row[column]);
}
}
}
}
baglanti.Close();
Eğer kullanıcı bir txt’den okuma yapacaksa maillerinin arasına bir boşluk bırakması veya her maili ; işareti ile bitirmesi yeterli olacak. Biz dosyadan okuduğumuz yazıyı dizilere böldük, ardından da dizi elemanlarına baktık hangisi bizim mail formatımıza uyuyor. Mail formatımız ise @ işaretinden sonra bir tane . işareti olmak zorunda.
FileStream fs = new FileStream(openFile.FileName, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);string[] mailAdres = sr.ReadToEnd().Split(new char[] { ';', ' ', '\r', '\n' });
foreach (string adres in mailAdres)
{
if (mailAdresKontrol(adres))
{
mailList_lb.Items.Add(adres);
}
}
Kişi listelerini dosyadan okudunktan sonra ‘Kişi Listesini Oluştur’ butonu ile kişi listesini XML dosyamıza kaydediyoruz.
Kişi Listesini Oluştur butonu;
privatevoid kisiListesiKayit_btn_Click(object sender, EventArgs e){if(!GirisKontrol()){return;}else{string[] mailList =newstring[mailList_lb.Items.Count];for(int i =0; i < mailList_lb.Items.Count; i++){ mailList[i]=(string)mailList_lb.Items[i];}
xmlYonetici.KisiListesiEkle(xmlYonetici.KisiListesiEnBuyukId()+1, kisiListesiAdi_tb.Text, mailList);}
MessageBox.Show("Kişi Listesi Başarıyla Oluşturuldu!", "www.burakozkan.net", MessageBoxButtons.OK, MessageBoxIcon.Information);
Temizle();}
private void kisiListesiKayit_btn_Click(object sender, EventArgs e)
{
if (!GirisKontrol())
{ return; }
else
{
string[] mailList = new string[mailList_lb.Items.Count];
for (int i = 0; i < mailList_lb.Items.Count; i++)
{ mailList[i] = (string)mailList_lb.Items[i]; }
xmlYonetici.KisiListesiEkle(xmlYonetici.KisiListesiEnBuyukId() + 1, kisiListesiAdi_tb.Text, mailList);
}
MessageBox.Show("Kişi Listesi Başarıyla Oluşturuldu!", "www.burakozkan.net", MessageBoxButtons.OK, MessageBoxIcon.Information);
Temizle();
}
Son menümüz oluşturduğumuz kişi listelerini düzenleyeceğimiz menü. Bu menüde oluşturduğumuz kişi listesinin adını değiştirebiliriz, mail listesinden biriniz çıkartıp ekleyebiliriz. Hesap düzenleme menüsüne çok benzer bir yapıya sahip, yine sol tarafta daha önceden tanımlamış olduğumuz kişi listelerinin adları sol taraftaki Listbox’da görebiliyoruz.
Ve ana menü. Ana menüde yapacağımız işlemler şunlar; kullanıcı önceden tanımlamış olduğu kişi listesini veya listelerini ekleyebilir ya da tek tek mail adreslerini ekleyerek de mail gönderebilir. Mailine isterse bir dosya ekleyebilir, kişi listesini belirledikten sonra ‘GÖNDER’ butonunu kullanarak belirlediği adreslere mailini gönderebilir;
class Hesap
{
#region Alanlar(Fields)
private int m_id;
private string m_hesapAdi;
private string m_mailAdresi;
private string m_mailSifresi;
private string m_smtpServer;
private int m_port;
private bool m_ssl;
#endregion#region Özellikler(Properties)
public int Id
{
get { return m_id; }
set { m_id = value; }
}
public string HesapAdi
{
get { return m_hesapAdi; }
set { m_hesapAdi = value; }
}
public string MailAdresi
{
get { return m_mailAdresi; }
set { m_mailAdresi = value; }
}
public string MailSifresi
{
get { return m_mailSifresi; }
set { m_mailSifresi = value; }
}
public string ServerAdres
{
get { return m_smtpServer; }
set { m_smtpServer = value; }
}
public int Port
{
get { return m_port; }
set { m_port = value; }
}
public bool SSL
{
get { return m_ssl; }
set { m_ssl = value; }
}
#endregionpublic Hesap(int id, string hesapAdi, string mailAdres, string mailSifresi, string mailServer, int port, bool ssl)
{
Id = id;
HesapAdi = hesapAdi;
MailAdresi = mailAdres;
MailSifresi = mailSifresi;
ServerAdres = mailServer;
Port = port;
SSL = ssl;
}public override string ToString()
{ return HesapAdi; }
}
Bir diğer sınıfımızda KisiListesi sınıfı, bu sınıfta yine Hesap sınıfı gibi kullanıcı kişi listesi oluşturmak için gerekli olan bilgileri alan değişkenlere sahip. Sınıfın yapısı;
class KisiListesi
{
#region Alanlar(Fields)
private int m_id;
private string m_kisiListeAdi;
private string[] m_kisiler;
#endregion#region Özellikler(Properties)
public int Id
{
get { return m_id; }
set { m_id = value; }
}
public string KisiListesiAdi
{
get { return m_kisiListeAdi; }
set { m_kisiListeAdi = value; }
}
public string[] MailListesi
{
get { return m_kisiler; }
set { m_kisiler = value; }
}
#endregionpublic KisiListesi(int id, string kisiListesiAdi, string[] mailListesi)
{
Id = id;
KisiListesiAdi = kisiListesiAdi;
MailListesi = mailListesi;
}public override string ToString()
{ return KisiListesiAdi; }
}
Kişi listesi oluşturmak için; -Mail listesi, -Kişi Listesinin Adı ve -ID gereklidir, .ToString() fonksiyonuda aynı Hesap sınıfında olduğu gibi Combobox, Listbox gibi elemanların .Items.Add(…) kısmına yazınca kişi listesinin adının gözükmesi için override edilmiştir.
Programı çok detaylı test etme imkanım olmadı, eksikleri ve hataları varsa şimdiden affınıza sığınıyorum. Programı kendi isteğinize göre güncelleyebilirsiniz. Programı buradan, kaynak kodlarını ‘Download’ menüsünden indirebilirsiniz. Her türlü fikir ve eleştirilerinizi bekliyorum. Umarım kendinize faydalı birşeyler bulabilirsiniz… Başka bir Ayın Konusunda görüşmek üzere..
Başlık için aslında ayın konusu değil programı demek daha doğru olur ama böyle başladı böyle devam etsin diye düşündüm :). Ağustos ayının son günü ilan ettiğim ‘Eylül Ayında Sitemde!‘ yazısındaki program ve makalelerin birini daha buraya ekleyerek şuan için sözümü tutduğum için çok mutluyum, umarım bu sistemin devamlılığını sağlayabilirim. Arkadaşlar daha önce yazmış olduğum ‘C# ile Windows Formuna Login Girişi!‘ makalesinin programını sitemin ‘Download’ bölümünden ve buradan indirebilirsiniz. Kodu düzenlerken makalede ufak birkaç değişiklik yaptım, tekrar gözden geçirmenizde fayda var. ‘Kullanıcı Ekle’ formunda ve ‘up_KullaniciEkle’ stored procedure’da değişikliklik oldu. Umarım sizler için faydalı olur..
Kolay gelsin, iyi çalışmarlar…
NOT:Programın Settings kısmından ConnectionString kısmını kendi veritabanınıza göre değiştirmeyi unutmayın!
Norton’nun ‘Live Update’ programını ya da Nokia’nın ‘Software Updater’ programını ve birçok programın bu tarz update programlarını görmüşsünüzdür. Bu tür programlar ana programdan bağımsız çalışırlar ve asıl iş yapan programı update ederler. Bizde kendi yaptığımız programa bu tür bir uygulama yapabiliriz. Yeni bir versiyon çıkarttığımızda kullanıcı yaptığımız update programını kullanarak çok rahat bir şekilde internetten update işlemini yapabilir. Şimdi biraz bu işlemi nasıl gerçekleştireceğiz onu konuşalım;
Öncelikle ana programımız internette bizim hazırladığımız bir txt dosyasından güncel versiyonu okuyup karşılaştırma yapması lazım, örnek vermek gerekirse bizim programımız v2.00 ise ve biz yeni versiyon v2.01 çıkartıyorsak bunu algılamamız lazım ana programda. Bunu istersek biz belirli aralıklarla kullanıcı fark etmeden, programımızı anti-virus yazılımı ile engellemediyse gizli olarak da yapabiliriz veya kullanıcı için ‘Güncelleştirme Kontrol’ butonu koyarak kullanıcının insiyatifinede bırakabiliriz. Ana programın yapması gerekenler bunlar. Peki update programı;
Ben adına ‘Live Update’ dediğim programda öncelikle yeni versiyonda indirilmesi gereken dosyaları tespit ediyorum, örneğin uygulamamız bir .jpg, .gif, .mdb, .dll, .txt vb. farklı türlerde dosya içerebilir, bunların hangilerinin değiştiği veya ekleneceğini tespit etmemiz lazım. Dosyaları tespit ettikden sonra sırasıyla hepsini exe’nin yanına bir temp klasörünün içine indiriyoruz, hemen hatırlatalım indirilecek dosyaları tespit ederken nereye kopyalanacağınıda belirtelim ki ileride bir sorun çıkmasın. Dosyaları tespit edeceğimiz örnek bir .txt dosyası;
Burayı açıklamak gerekirse ilk parametre ana programın yanında hangi klasör’e kopyalanacağını temsil ediyor, biz eğer dosyadan okuma işlemi yapıyorsak klasör adı bizim için çok önemli. Ikinci parametre ise dosyanın adı ve son parametre internetdeki klasörün adını veriyoruz yani ‘KizKulesi.jpg’ dosyası; www.burakozkan.net/updateDeneme/resim/KizKulesi.jpg adresinde. Bu dosyanın en sonuna ana programımızı yazıyoruz, tüm ek dosyalar indirildikten sonra ana programı da yazarak update işlemini tamamlamış oluyoruz.
Ben sizler için bir tane update edilebilir ‘Değerlerimiz’ ve ‘Değerlerimiz Live Update’ ismini verdiğim iki program yaptım, buradan indirdiğiniz program update edilebilir bir programdır. Indirdikten sonra ki yenilikleri fark edeceğinizden şüphem yok :), toplam 4 tane yenilik var bakalım hepsini kim fark edecek :).
Programdan Resimler;
Update edilebilir uygulamayı buradan indirebilirsiniz. Programın kaynak kodları ‘Download’ menüsünde mevcutdur.
Herkese merhabalar, arkadaşlar daha önceden gmail ile mail gönderme isimli bir yazı yazmıştım, bunun hotmail versiyonunu yazmak istedim. Aslında bunu şöyle genelleyebiliriz, pop3 desteği veren tüm mailleriniz ile C# üzerinden sorunsuz bir şekilde veri gönderebilirsiniz. Aşağıda pop3 ayarları ve kod parçacığını veriyorum umarım faydalı olur.
POP server: pop3.live.com (Port 995) POP SSL required? Evet User name: Windows Live ID yazınız, [email protected] Password: Mail adresinizin şifresi SMTP server: smtp.live.com (Port 25) // Türk Telekom bu port’u kapattığı için biz 587 port numarasını kullanmalıyız. Authentication required? Evet TLS/SSL required? Evet
Programı çalıştırdığınızda karşınıza şöyle bir hata çıkıyorsa; ‘The ‘Microsoft.Jet.OLEDB.4.0′ provider is not registered on the local machine.’ yapmanız gereken çok basit bir işlem. Projenize sağ tıklayıp ‘Properties->Build->Platform Targer->x86’ olarak derleyip tekrar çalıştırdığınızda probleminiz çözülmüş olacaktır. Sorunun çözümünden sonra nedeninide açıklayalım, projenizde Access veya Excel kullanıyorsanız 64bit işletim sistemlerinde karşınıza bu hata çıkacaktır şayet makinede Office uygulaması yüklü değilse. Jet Oledb uygulaması sistemde yüklü değilse, uygulama 64-Bit işletim sistemini desteklemiyorsa veya Access yada Excel uygulamamıza 64bit işletim sistemlerinde erişemiyorsak bu hata ile karşılaşabiliriz.
Uygulamanızda teknik destek için, dosya gönderimi vb. ihtiyaçlar için mail gönderimi gerekebilir. Ben Gmail ile nasıl bu işlemi yapılacağını anlatacağım ama hangi mail servisiniz kullanıyorsanız onun port numarasını ve smtp adresini alarak gönderbilirsiniz, gmail olmak gibi bir zorunluluğu yok.
Burada kendi kendimize bir mail göndermiş oluyoruz. Textbox ile kullanıcının mail adresini alıp geri dönüş yapabiliriz. ‘Yolla_SendCompleted’ bu fonksiyonun altında başarılı ise kullanıcıya otomatik bir mesaj yollayabiliriz. Kod kısmını inceleyecek olursak, MailMessage türünden MailYolla sınıfı oluşturuyoruz, burada Mail’i kime göndereceğimizi, mesajımızı, eklenecek dosya varsa eklenecek dosyaları bu sınıfın özelliklerinden faydalanarak yapıyoruz. Ardından SMTP türünden Yolla adında bir sınıf değişkeni oluşturuyoruz. Bu sınıfın özelliklerine de port, mail adresi, mail şifresi vb. özellikleri giriyoruz ve en son olarak Yolla.SendAsync(…) fonksiyonu ile maili gönderiyoruz. ‘Yolla_SendCompleted’ isimli fonksiyon mail gönderme işlemi başlayınca tetiklenir ve işlemler yapılır. Umarı faydalı olur sizlere…
Yaptığımız uygulamalarınçalışması için önceden bir ‘Kullanıcı Adı’ ve ‘Şifre’ sorarak çalışmasını isteyebiliriz. Bunun için bir çok algoritma geliştirilebilir. Bu makalede benim izleyeceğim yol, ‘Kullanıcı Adı’ ve ‘Şifre’ bilgilerini bir veritabanında tutmak olacak, hatta kullanıcının ‘Yetki’lerini de veritabanında tutarak uygulamamızda kullanıcıya özel yetkiler verebiliriz. Aşağıdaki resimde kullanıcı ve yetki bilgilerinin veritabanı tasarımı SQL Server 2005’de yapılmış olarak gösterilmektedir.
Tasarımı incelersek; ‘Yetki’ tablosu bizim uygulamamıza özel yetkileri içeriyor. Mesela bir ürün takip otomasyon’u yapıyorsak, ‘Stok Gir’, ‘Stok Çık’ bunlar yetki olabilir ve depo bölümünü ilgilendiren yetkilerdir, aynı şekilde ‘Cihaz Üretime Hazırla’ gibi bir yetki’de üretim bölümünü ilgilendiren bir yetkidir. Uygulamamızda birde ‘Admin’ yetkisi olur bu yetki de yeni kullanıcı ekleyebilir, yetkileri değiştirebilir. Bunu yapması için de Yetkilerin adlarını da tutmamız Admin için daha anlaşılır yapar. ‘Kullanicilar’ tablosuda ‘KullaniciNo’, ‘KullaniciSifre’ ve ‘KullaniciAdi’ tutar bu tablo da ‘Kullanıcı Adı’ ve ‘Şifre’ bilgileri tutulur. ‘Kullanıcı No’ tek bir ‘Kullanıcı Adı’ ve ‘Şifre’ olacağı için primary key olarak tanımlanmışdır. Son olarak ‘Izin’ tablosu da ‘Kullanıcı No’, ‘Yetki No’ ve ‘ErisebilirMi’ sütunlarından oluşuyor. Bu tabloyu incelersek, Kullanıcı No’yu primary key yapamayız çünkü bir kullanıcınınbirden fazla yetki’si olabilir, yetki’yide primary key yapamayız çünkü bir yetki birden fazla kullanıcı için kullanılabilir, ‘ErisebilirMi’ sütunuda zaten primary key olması söz konusu değil, bu tablo KullanıcıNo ve Yetki tablosunun birbirine bağlayan bir tablodur. Veritabanı kısmı tasarımımız bittikden sonra şimdi uygulamamızı tasarlayalım.
‘Kullanıcı Adı’ ve ‘Şifre’ soran basit bir form tasarımı hazırladık. Tüm menüler deaktif, kullanıcı şifre girmeye başladığı zaman ‘Tamam’ butonuda aktif olacak şekilde hazırladık. Şimdi veritabanına birkaç kullanıcı, yetki ve izin ekleyelim.
Yukarıda bazı yetki’ler, kullanıcılar ve izin’ler belirledik, kullanıcıya göre yetki verdik. Şimdi farklı kullanıcılarla giriş yapalım ve bakalım uygulamamızda doğru yerler aktif oluyor mu. Murat kullanıcısının sadece ‘Stok Gir’ ve ‘Stok Çık’ yetkisi verdik, Burak kullanıcısına bu yetkileri vermedik, sadece ‘Admin’ ve ‘Ürün Hazırlama’ yetkisi verdik.
Formumuzdan ‘Murat Özkan’ kullanıcı adı ile giriş yapıldığında;
‘Burak Özkan’ kullanıcı adı ile giriş yaptığında;
Farklı kullanıcı girişlerinde farklı yerler aktif oldu, peki bunu nasıl yaptık? İşin kod kısmını biraz inceleyelim. Önce ‘Tamam’ butonunun ‘Click’ eventinde olanları yazalım;
Kod’u incelediğimizde veritabanı’nın ‘Kullanıcı’ tablosundan ‘Kullanıcı Adı’na göre şifresini alıyoruz ve girilen şifreyle karşılaştırıyoruz. Eğer şifre doğruysa yetkilerini yüklüyoruz aksi durumda hata verip hiçbir menüyü aktif etmeden fonksiyonu bitiriyoruz.Şimdi ‘YetkileriniYukle()’ fonksiyonunu inceleyelim;
private bool YetkileriniYukle()
{
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = Properties.Settings.Default.ConnectionString; cnn.Open();
DataSet ds = new DataSet();
SqlDataAdapter sda = new SqlDataAdapter("select YetkiNo, ErisebilirMi from Izin where KullaniciNo = '" + KullaniciNo + "'", cnn);
sda.Fill(ds);
if ((ds.Tables.Count == 0))
{
MessageBox.Show("Yetkiler Yüklenemiyor.", "Otomasyon", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
for (int i = 0; i < ds.Tables[0].Rows.Count; ++i)
{
int yetkiIndis = (int)ds.Tables[0].Rows[i][0];
YetkiDizisi[yetkiIndis] = (bool)ds.Tables[0].Rows[i][1];
}
return true;
}
Bu fonksiyonda da KullaniciNo’ya göre Izin tablosundan yetkileri aldık, bir tane global YetkiDizi’miz var, veritabanından verdiğimiz yetkilere göre YetkiDizi’si dolduruluyor, yetkiIndis’de sıralı olmayacağı için Izın tablosundanki YetkiNo’ya göre dolduruluyor böylece programda ki indis’le veritabanında ki YetkiNo aynı olmuş oluyor.Son olarakda kullanıcı ekleme, silme, şifre değiştirme ve kullanıcının yetkilerini belirleme kısmını yapalım;
Yukarıdaki şekilde form’larımızı tasarladık, bu işlemleri yapmak için ‘Stored Procedure’ kullanacağız. Ilk olarak Kullanıcı Sil formunu inceleyelim;
Form’un Load kısmı ve button1_Click event’i şöyle;
Form ilk açıldığında Kullanıcılar veritabanından yükleniyor, ‘Kullanıcı Sil’ butonunda SQL Serverda hazırladığımız ‘@KullanıcıNo’ parametresi alan stored procedure çağırıyoruz;
Stored Procedure;
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER proc [dbo].[up_KullaniciSil]@KullaniciNo intasbeginbegin tran
begin try delete from Izin where KullaniciNo = @KullaniciNo end try begin catch rollback tran return end catch
begin try delete from Kullanicilar where KullaniciNo = @KullaniciNo end try begin catch rollback tran return end catch
commit tran end
Yetkilendirme ayarları formunu belirlediğimiz yetkilerin isimlerine sahip olan checkBox ekliyoruz. FormLoad kısmında yine kullanıcıları yüklüyoruz, seçilen kullanıcıların yetkileri seçilmiş oluyor.FormLoad ve ‘UYGULA’ butonun kod kısmı aşağıdaki gibi;
private static CheckBox[] cbDizi = new CheckBox[7];
public string KullaniciAdi;
public int KullaniciNo;
private DataSet dsKullanicilar;
private void YetkilendirmeAyarlari_Load(object sender, EventArgs e)
{
cbDizi[0] = Yetki0;
cbDizi[1] = Yetki1;
cbDizi[2] = Yetki2;
cbDizi[3] = Yetki3;
cbDizi[4] = Yetki5;
cbDizi[5] = Yetki6;
cbDizi[6] = Yetki13;
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = Properties.Settings.Default.ConnectionString;
cnn.Open();
dsKullanicilar = new DataSet();
SqlDataAdapter sda = new SqlDataAdapter("select * from Kullanicilar", cnn);
sda.Fill(dsKullanicilar);
if (dsKullanicilar.Tables.Count == 0)
{
MessageBox.Show("Kullanıcılar Yüklenemiyor.", "Otomasyon", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
for (int i = 0; i < dsKullanicilar.Tables[0].Rows.Count; ++i)
{ comboBox1.Items.Add(dsKullanicilar.Tables[0].Rows[i][2].ToString()); }
}
private void button1_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Yetkileri Değiştirmek İstediğinize Eminmisiniz?", "Otomasyon", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes)
{ return; }
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = Properties.Settings.Default.ConnectionString;
cnn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = cnn;
cmd.CommandText = "up_KullaniciYetkiDegistir";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@KullaniciNo", KullaniciNo);
cmd.Parameters.AddWithValue("@Yetki0", Yetki0.Checked);
cmd.Parameters.AddWithValue("@Yetki1", Yetki1.Checked);
cmd.Parameters.AddWithValue("@Yetki2", Yetki2.Checked);
cmd.Parameters.AddWithValue("@Yetki3", Yetki3.Checked);
cmd.Parameters.AddWithValue("@Yetki5", Yetki5.Checked);
cmd.Parameters.AddWithValue("@Yetki6", Yetki6.Checked);
cmd.Parameters.AddWithValue("@Yetki13", Yetki13.Checked);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
MessageBox.Show("Yetkiler Başarıyla Değiştirildi.", "Otomasyon", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = Properties.Settings.Default.ConnectionString;
cnn.Open();
for (int i = 0; i < dsKullanicilar.Tables[0].Rows.Count; ++i)
{
if ((string)dsKullanicilar.Tables[0].Rows[i][2] == comboBox1.Text)
{ KullaniciNo = (int)dsKullanicilar.Tables[0].Rows[i][0]; }
}
DataSet ds = new DataSet();
SqlDataAdapter sda = new SqlDataAdapter("select YetkiNo, ErisebilirMi from Izin where KullaniciNo = '" + KullaniciNo + "'", cnn);
sda.Fill(ds);
if ((ds.Tables.Count == 0))
{
MessageBox.Show("Yetkiler Yüklenemiyor.", "Otomasyon", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
for (int i = 0; i < ds.Tables[0].Rows.Count; ++i)
{
int yetkiIndis = (int)ds.Tables[0].Rows[i][0];
cbDizi[yetkiIndis].Checked = (bool)ds.Tables[0].Rows[i][1];
}
}
Her kullanıcı için cbDizi setleniyor. cbDizi, chechBox’lardan oluşan bir dizi ve veritabanımızdaki YetkiNo ile aynı indis’e sahip.
Stored Procedure;
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER proc [dbo].[up_KullaniciYetkiDegistir]
@KullaniciNo int,
@Yetki0 int,
@Yetki1 int,
@Yetki2 int,
@Yetki3 int,
@Yetki4 int,
@Yetki5 int,
@Yetki6 int,
as begin
update Izin set ErisebilirMi = @Yetki0 where KullaniciNo = @KullaniciNo and YetkiNo = 0
update Izin set ErisebilirMi = @Yetki1 where KullaniciNo = @KullaniciNo and YetkiNo = 1
update Izin set ErisebilirMi = @Yetki2 where KullaniciNo = @KullaniciNo and YetkiNo = 2
update Izin set ErisebilirMi = @Yetki3 where KullaniciNo = @KullaniciNo and YetkiNo = 3
update Izin set ErisebilirMi = @Yetki4 where KullaniciNo = @KullaniciNo and YetkiNo = 4
update Izin set ErisebilirMi = @Yetki5 where KullaniciNo = @KullaniciNo and YetkiNo = 5
update Izin set ErisebilirMi = @Yetki6 where KullaniciNo = @KullaniciNo and YetkiNo = 6
end
Kullanıcı şifresini değiştirmek isteyebilir, bunun için ana form’dan giriş yaptıkdan sonra aşağıdaki işlemle kendi şifresini değiştirebilir. ‘DEĞİŞTİR’ butonuna basıldıkdan sonra yapılan işlemler aşağıdaki gibi;
private void button1_Click(object sender, EventArgs e)
{
if ((eskiSifre_tb.Text == "") || (yeniSifre_tb.Text == ""))
{
MessageBox.Show("Lütfen Eski ve Yeni Şifrenizi Giriniz", "Otomasyon", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (eskiSifre_tb.Text != KullaniciSifre)
{
MessageBox.Show("Eski Şifrenizi Lütfen Doğru Giriniz", "Otomasyon", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (MessageBox.Show("Şifre Değişikliğini Onaylıyormusunuz?", "Otomasyon", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes)
{ return; }
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = Properties.Settings.Default.ConnectionString;
cnn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = cnn;
cmd.CommandText = "up_KullaniciSifreDegistir";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@KullaniciAdi", KullaniciAdi);
cmd.Parameters.AddWithValue("@KullaniciSifre", yeniSifre_tb.Text);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{ MessageBox.Show(ex.Message); return; }
MessageBox.Show("Şifre Başarıyla Değiştirildi", "Otomasyon", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Burada eski şifreyi nasıl karşılaştırdığımızı sorabilirsiniz, bu form’da bir tane string türünden public ‘KullaniciAdi’ ve ‘KullaniciSifre’ tanımlıyoruz. Bu form’u ilk ana form’da çağırdığımız için kullanıcının adını ve şifresini zaten biliyoruz.
Stored Procedure;
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO
ALTER proc [dbo].[up_KullaniciSifreDegistir]
@KullaniciAdi varchar(50),
@KullaniciSifre varchar(50)
as begin
update Kullanicilar set KullaniciSifre = @KullaniciSifre where KullaniciAdi = @KullaniciAdi
end
Son olarak admin yetkisine sahip olan kişinin kullanıcı ekleme işlemine geldi. Ben burada yeni kullanıcılar için şifreyi sabit ‘otomasyon’ olarak belirledim. Yeni kullanıcı ilk kez girdikden sonra şifresini değiştirebilir, admin de kullanıcının yetkilerini sonradan belirler.’Kullanıcı Ekle’ butonuna basılınca yapılan işlem;
Yine SQL Server’da tanımlamış olduğumuz bir stored procedure çağırarak kullanıcı ekliyoruz.
Stored Procedure;
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER proc [dbo].[up_KullaniciEkle]
@KullaniciAdi varchar(50),
@KullaniciSifre varchar(50)
as begin
declare @KullaniciNo varchar(30);
set @KullaniciNo = ((select Count(*) from Kullanicilar) + 1)
insert into Kullanicilar values(@KullaniciNo, @KullaniciSifre, @KullaniciAdi)
end
Genel olarak Login form tasarımı bu şekilde elbette üstüne birkaç özellik daha koyarak geliştirilebilir. Umarım sizlere faydalı olur. Başka bir makalede görüşmek üzere.
Okul, İş, Kurs derken sitemi çok boşladım. Şu anda C ve Sistem Programcıları derneğinde ‘MS-Sql Server ve Oracle’ Programlama dersi alıyorum. O kursla beraber güzel bir otomasyon programı çalışmalarımda sürüyor. Sizinlerinde işinize yarayacağını düşündüğüm ufak bir kod parcası vermek istedim. Aşağıdaki kod Ms-Sql Server’da yaptığım bir Stored Procedure çalıştırıyor. Stored Procedure nedir? diye soranlaırnız mutlaka vardır. Bu sorunun cevabını burada vermeyeceğim. Çok kısa bir zaman sonra Ms-Sql Server ile ilgili daha çok makale bulabileceksiniz.
Kod parçasını kısaca açıklamak gerekirse, SqlCommand’ın CommandText’ine yazdığımız stored procedure’un ismini cmd.Parameters.AddWithValue ile yazdığınız procedure’un adını ve ona verdiğiniz değeri giriyorsunuz. Son olarak da cmd.ExecuteNonQuery diyerek stored procedure çalıştırıyorsunuz.
Burak ÖZKAN; 2008 yılı, İstanbul Üniversitesi End. Otomasyon bölümü ve 2012 Kadir Has Üniversitesi Bilgisayar Müh. bölümü mezunu, iyi bir yazılımcı olmak için çok çalışıyor ve çalışmaya devam edecek.
Son Yorumlar