Bugün daha önce yazmış olduğum Setup & ConnectionString yazısına ek yapacağız. Söz konusu ek; mdfDataFile ve ldfLogFile dosyalarını VeritabanıDatabase sunucusuna eklemekAttach.
İlk öğrenmemiz gereken bu işi yapan DDL kodları; (şu yazıda bunu nasıl yapabileceğiniz görebilirsiniz)
CREATE DATABASE [ornek] ON (FILENAME = N'E:\DataBases\ornek.mdf'), (FILENAME = N'E:\DataBases\ornek_log.ldf') FOR ATTACH
Daha sonra bu kodları kurulumsetup sırasında (OnAfterInstall) Ado.Net komutları ile çalıştırmakExecute etmek.
//DDL kodlarını oluşturalım StringBuilder sb = new StringBuilder(); sb.Append("CREATE DATABASE [Ornek] ON\r\n"); sb.AppendFormat("(FILENAME = N'{0}'),\r\n", thisAss.Location.Replace( thisAss.GetName().Name + ".exe", "ornek.mdf") ); sb.AppendFormat("(FILENAME = N'{0}')\r\n", thisAss.Location.Replace( thisAss.GetName().Name + ".exe", "ornek_log.ldf") ); sb.Append("FOR ATTACH\r\n"); //oluşan DDL kodlarını ADO.NET ile çalıştıralım using (SqlConnection con = new SqlConnection(value.Replace("ornek", "Master"))) { using (SqlCommand com = new SqlCommand( sb.ToString(), con)) { con.Open(); com.ExecuteNonQuery(); } }
Decimal kadar büyük Integer kadar tam değer saklamak isterseniz alın size BigInteger. Baştan ifade edeyim bu bir Buit-in TypeYerleşik Tip değil bir StructYapı dır ve sadece .Net Framework 4.0 ile kullanabilirsiniz.
Son olarak, bu yapıyı kullanabilmek için System.Numerics namespace ini referans olarak projenize eklemeniz gerekir.
class Program { static void Main(string[] args) { //en büyük decimal değer decimal dec = decimal.MaxValue; //decimal değerden biginteger oluşturalım BigInteger big = new BigInteger(dec); //ekranda gösterelim Console.WriteLine("dec={0}\nbig={1}", dec, big); //bir arttıralım big++; //bakalım artmış mı? Console.WriteLine("\nbig={0}", big);
//Math sınıfı kullanılamadığı için BigInteger max1 = Math.Max(big1, big2); //kendi metotları mevcut BigInteger max2 = BigInteger.Max(big1, big2);
Geçenlerde bir uygulama için Captcha örneği hazırlıyoruz. Test aşamasında iken güvenilirliğini nasıl test edebiliriz diye düşündüm. Akabinde aklıma MS OneNote uygulaması geldi. Ms Outlook'tan sonra en sık kullandığım ikinci MS Office uygulamasıdır. Uygulamanın özellikleri saymakla bitmez ama bizi ilgilendiren ise bir çeşit OCR özelliği barındırmasıdır. Bu özellik sayesinde resimlerin içindeki metinleri ayrıştırabiliryorsunuz.
Resime sağ tıkla ve metni ayrıştır.
Basit bir örnek ile başlayalım.
Arial 14 gri üzerine siyah metin. Sonuç -> 5TSRB5
İki çizgi atalım Sonuç - > KW4
Arka planı HatchBrush ile değiştirelim Sonuç -> String.Empty :)
Not: Bu test 100% güvenilir değildir. Daha iyi algoritmalar ile ayrıştırma daha başarılı olabilir.
Örnek proje.
Windows tabanlı uygulama geliştirirken başlangıçta yüklü işlemleriniz olmasa bile çok fazla kontrol yada yüksek hacimli arkaplan resimleri kullanıldığında parça parça erkrana gelen kontroller yada kilitlenmeler kaçınılmaz olabiliyor.
Bu gibi durumlarda çözüm olarak Applicationuygulama Classnesne sının Idle Eventolay i kullanılabilir. Bu olay yardımı ile bir işlemin bittiği ve beklemeIdle durumuna geçtiği anlaşılabilir.
Örnekte; Form Opacitysaydamsızlık özellliği 0 yapılarak gizlenir. (Uygulamayı simüle etmek için Load olayında 3000 milisaniye bekleme sözkonusu) İşlem bittiğinde ise Opacity özelliği ile Form gösterilir.
public Form1() { Opacity = 0; InitializeComponent(); listBox1.Items.Add(string.Format("Initialize -> {0:HH:mm:ss}", DateTime.Now)); Application.Idle += new EventHandler(Application_Idle); } void Application_Idle(object sender, EventArgs e) { listBox1.Items.Add(string.Format("Idle -> {0:HH:mm:ss}", DateTime.Now)); Opacity = 1; Application.Idle -= new EventHandler(Application_Idle); } private void Loading_Load(object sender, EventArgs e) { listBox1.Items.Add(string.Format("Processing -> {0:HH:mm:ss}", DateTime.Now)); Thread.Sleep(3000); } private void button1_Click(object sender, EventArgs e) { listBox1.Items.Add(string.Empty); listBox1.Items.Add(string.Format("Processing -> {0:HH:mm:ss}", DateTime.Now)); Thread.Sleep(3000); }
Burada dikkat edilmesi gereken en önemli husus, görevi bittiğinde Idle olayının kaldırılmasıdetach gerekiyor.
Aksi takdirde olay sürekli tetiklenecektir.
Geçenlerde herhangi bir uygulama geliştiriyordum ki aniden bir kontrol ihtiyacım oldu. Söyle ki;
Bir Classnesne oluşturdum.
public class Employee { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public decimal Salary { get; set; } public DateTime HireDate { get; set; } }
Daha sonra kopyasınıinstance çıkarıp özelliklerine değer atadım. Buraya kadar herşey normal. Peki dedim şunu birde WebForm'unda zahmetsiz bir şekilde gösterebilsem ne süper olur. Böyle durumda akla en yatkın DetailsView veri kontrolü kullanmaktır. Lakin kontrolün DataSource özelliğine herhangi bir nesneyi zart diye atayamazsınız. Eğer atarsanız şöyle bir hata alırsınız
Hoş değil :(
Bu gibi durumlarda olmasa ne zaman kontrol geliştireceğiz ki :) Peki ne yapmak lazım; Mantık basit. Reflection ile nesne özelliklerini okumak, kontrolün ihtiyaç duyabileceği ekstra bilgileri Attributenitelik yardımı ile iletmek.
[Serializable] public class Employee { [FieldAttributes(IsVisible = false)] public int ID { get; set; } [FieldAttributes(FieldHead = "Ad")] public string FirstName { get; set; } [FieldAttributes(FieldHead = "Soyad")] public string LastName { get; set; } [FieldAttributes(FieldHead = "Maaş", Format = "N2")] public decimal Salary { get; set; } [FieldAttributes(FieldHead = "İşe Başlama Tarihi", Format = "dd.MM.yyyy")] public DateTime HireDate { get; set; } }
Kullanımın kolay olması için SmartTag ve DesignTimeSupport gibi atraksiyonlar.
Sonuç;
Proje dosyası.
Metotlar geriye değer döndürür yada döndürmez. Peki döndürenler kaç değer döndürür denildiğinde tabi ki bir deriz. Birden fazlaya ihtiyaç varsa ne yaparız? Bunun için 3 metot prototipi yazdım, paylaşıyorum.
class Program { static void Main(string[] args) { //1. yöntemin kullanımı int a, b; a = Yontem1(out b); // sonuc //a -> 20 ve b -> 10 olur. } //1. yöntem -> out kullanımı static int Yontem1(out int par) { par = 10; return 20; }
İlk yöntem out parametre anahtarını kullanmak. Geriye dönmediği kesin ama metottan etkilendiğide bir gerçek. İşe yarıyor mu, evet :)
class Program { static void Main(string[] args) { //2. yöntemin kullanımı DonenTip tip = Yontem2(); //sonuc //tip.a -> 20 ve tip.b -> 10 olur. } //2. yöntem -> sınıf(class) kullanmak class DonenTip { public int a, b; } static DonenTip Yontem2() { DonenTip tip = new DonenTip(); tip.a = 20; tip.b = 10; return tip; }
İkinci yöntem ise Classnesne (Custom Reference Type) kullanmak. Geriye yine tek bir nesne dönüyor. İçsel olarak genişletilebilmesi (property, field) sayesinde çok kullanışlı lakin yazması zahmetli.
class Program { static void Main(string[] args) { //3. yöntemin kullanımı var sonuc = Yontem3(); //sonuc.Item1 -> 20 ve sonuc.Item2 -> 10 olur. } //3. yöntem Tuples kullanımı static Tuple<int, int> Yontem3() { return Tuple.Create(20, 10); }
Son yöntem aslında yazının amacı ve Framework 4.0 yeniliği olan Tupleçok-ögeli kullanmak...
Repeater, veri kontrolleri içinde en sevdiğimdir. Onu esnek hale getiren basit yapısı da ben en cezbeden özelliğidir. Basit olduğundan dolayı görevi sadece veri göstermek. Peki sıralama yapmak istersek ne yapmalıyız? Aslında cevap basit; HeaderTemplate içine LinkButton kontrolü yerleştirip, sıralama bilgilerini de ViewState içinde tutacağız.
Burada tablotable başlıklarına birer LinkButton ve Image kontrolü koyuyoruz. LinkButton sıralama komutunu işlerken, Image kontrolleri de sıralama yapılan satırları işaret edecek.
<HeaderTemplate> <table> <tr class="head"> <th style="width: 65%"> <asp:LinkButton ID="h1" runat="server" Text="Product Name" CommandName="name" CommandArgument="ProductName" /> <asp:Image ID="ProductName" runat="server" ImageAlign="AbsMiddle" /> </th> <th style="width: 20%"> <asp:LinkButton ID="h2" runat="server" Text="Unit Price" CommandName="price" CommandArgument="UnitPrice" /> <asp:Image ID="UnitPrice" runat="server" ImageAlign="AbsMiddle" /> </th> <th style="width: 15%"> <asp:LinkButton ID="h3" runat="server" Text="Unit Stok" CommandName="stock" CommandArgument="UnitsInStock" /> <asp:Image ID="UnitsInStock" runat="server" ImageAlign="AbsMiddle" /> </th> </tr> </HeaderTemplate>
Sıralama sırasından iki adet bilgiye ihtiyaç var. Sıralanacak veri kolonu ve sıralama yönü. Bu bilgileri ViewState içinde saklıyoruz. Kullanım kolaylığı olması için Propertyözellik olarak tanımlıyoruz.
public string SortOrder { get { if (ViewState["SortOrder"] == null) ViewState["SortOrder"] = "Asc"; return ViewState["SortOrder"].ToString(); } set { ViewState["SortOrder"] = value; } } public string SortColumn { get { if (ViewState["SortColumn"] == null) ViewState["SortColumn"] = "ProductName"; return ViewState["SortColumn"].ToString(); } set { ViewState["SortColumn"] = value; } }
Sıralama komutu için yazılacak Ado.Net kodları.
"Kolon adı parametre olmadığı için String nesnedinin Format metotunu kullandım."
void GetData() { SqlConnection con = new SqlConnection( "Data Source=.;Initial Catalog=Northwind;Integrated Security=True"); string query = string.Format( "Select ProductName,UnitPrice,UnitsInStock From Products Order by {0} {1}", SortColumn, SortOrder); SqlCommand com = new SqlCommand( query, con); con.Open(); rpt1.DataSource = com.ExecuteReader(); rpt1.DataBind(); con.Close(); }
Uygulama sonunda elde edeceğimiz veri listesi.
Kalan detaylara projeyi indirip bakabilirsiniz.
Projeyi indir.
Öyle bir tablotable olsun ki sınırsız kategori ve alt kategori ekleyebileyim. Neden bahsettiğimi anladınız sanırım :) Halk arasında Sınırsız Ağaç Yapısı denilen tablo çeşidi.
Örnek tablo:
Yapı şöyle olacak; Kategori, hiyerarşinin en üstünde ise alt kategori değeri 0sıfır değilse üst kategorinin id değeri yer alacak. Örneğin; Kitap, kendi kategorisinde en tepede yani alt kategori değeri 0. Dünya Klasikleri ise Kitap kategorisinin altında olduğu için alt kategori değeri Kitap kategorisinin CategoryID değeri olacak yani 1 gibi ...
Azıcık kod yazalım. Kategori tablosunu DataTable nesnesine doldurarak başlayalım. Bu hamle işimizi bi hayli kolaylaştıracaktır. Daha sonra recursiveyinenelen bir metot yardımıyla kategori ve alt kategori bitinceye kadar dönelim. Son olarak ta elde ettiğimiz değerleri Treeview controlülüne nodedüğüm olakarak ekleyelim.
"Eğer karışık geldi ise biraz recursive çalışın."
DataTable dt = new DataTable(); protected void Page_Load(object sender, EventArgs e) { SqlConnection con = new SqlConnection( "Data Source=.;Initial Catalog=Ordek;Integrated Security=True"); SqlDataAdapter dap = new SqlDataAdapter( "select * from Category order by SubCategoryID", con); dap.Fill(dt); populateData(TreeView1.Nodes[0], getrows("0")); } DataRowCollection getrows(string id) { DataView dw = new DataView(dt); dw.RowFilter = "SubCategoryID=" + id; return dw.ToTable().Rows; } void populateData(TreeNode node, DataRowCollection col) { foreach (DataRow row in col) { TreeNode n = new TreeNode(row[1].ToString()); node.ChildNodes.Add(n); populateData(n, getrows(row[0].ToString())); } }
"Hatasız bir uygulama yazmak için kullanıcıyı ortadan kaldırmaktır" (sanırım buna benzer bir şeydi) diye duymuştum bir zamanlar. Yazılımlarımızda hatalar olacak. Bu kaçınılmaz ama en aza indirmek içinde çaba sarfetmek te bizim görevimiz. Lakin bunun için her yere try cacth blokları da koymak pek mantıklı bir yaklaşım değil:) Bu durumlar için, özellikle web uygulamalarında Error Feedback denilen bir yöntem çok sık kullanılır. Amaç; çalışma zamanı bir sayfada ya da ona bağlı bir uygulamada hata oluştuğunda, hata ile ilgili detayların geliştiriciye e-mail olarak gönderilmesi daha sonra da kullanıcıya hata mesajı yerine basit bir html sayfası gösterilmesinden ibaret.
Error isiminde bir classnesne oluşturalım. Oluşan hata ile ilgili gerekli bilgileri birer özellikproperty olarak belirleyelim. Time : Hata ne zaman oluştu? Message : Oluşan hata nedir? -> Exception.Message Ip : Hataya maruz kalan kullanıcı Ip adresi nedir? Page : Hatanın oluştuğu sayfa hangisi? Details : Oluşan hatanın detayları? -> Exception.Source
public class Error { public DateTime Time { get; set; } public string Message { get; set; } public string Ip { get; set; } public string Page { get; set; } public string Details { get; set; } }
Gönderilecek Feefback için güzle bir html şablonu oluşturalım. Şablon içinde bilgi gireceğimiz alanları küme parantez parametreleri ile işaretleteyim ki String nesnesini Format metotu ile rahatça kullanabilelim. Oluşan şablonu App_Data klasörünün altına koyuyoruz.
Error nesnesine hizmet edecek ErrorProvider adında yardımcı bir nesne daha oluşturuyoruz. Nesneye CreateMessage adında static bir metot ekliyoruz. Metotun görevi; daha önce hazırladığımız şablonu okumak ve parametre olarak verilen error nesnesinden gelen bilgileri şablondaki gerekli yerlere yerleştirmek. Son olarakta oluşan bilgiyi e-mail olarak göndermek. (SendMail metotu için projeye bakınız)
public class ErrorProvider { public static void CreateMessage(Error error) { string content = File.ReadAllText( HttpContext.Current.Server.MapPath("App_Data/error.txt")); content = string.Format( content, error.Time.ToString("dd.MMM.yyyy HH:mm"), error.Page, error.Ip, error.Message, error.Details); SharedClass.SendMail( "developer@domain.com", "Raise Error", content); } }
Herşey tamam gibi. Sırada oluşabilecek hataları elde elebileceğimiz Global Application Class' ından yardım almaya geldi. Global.asax ' ın Application_Error adlı metotu, uygulama içinde hata oluştuğunda otomatik devreye girer. Bizde burada devreye girip ihtiyacımız olab kodları yazıyoruz.
protected void Application_Error(object sender, EventArgs e) { Exception exteption = Server.GetLastError(); Error error = new Error(); error.Message = exteption.Message; error.Details = exteption.Source; error.Time = DateTime.Now; error.Page = Request.UrlReferrer.AbsoluteUri; error.Ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (error.Ip == null || error.Ip == string.Empty || error.Ip == "unknown") error.Ip = Request.ServerVariables["REMOTE_ADDR"]; ErrorProvider.CreateMessage(error); Server.ClearError(); }
Son bir adım kaldı. Kullanıcı hata mesajları yerine bizim belirlediğimiz sayfaları görsün.
<customErrors mode="On" defaultRedirect="~/Error/GenericErrorPage.htm"> <error statusCode="403" redirect="~/Error/NoAccess.htm"/> <error statusCode="404" redirect="~/Error/FileNotFound.htm"/> </customErrors>
web.config dosyası içindeki customError -> mode özelliğini On olarak değiştiriyoruz. Daha sonra error alt düğümleri ile olası hatalar için uygun sayfaların yollarını redirect özellikleri ile belirttikten sonra uygulamada bitmiş oluyor.
Birden çok aşaması olan uygulamalarda geçici olarak dosya oluşturmak için metot yazmak yerine Path nesnesinin GetRandomFileName metotunu kullanabilirsiniz.
Path.GetRandomFileName();
rd1gm02e.hyt
Bu dosyalarıda geçici bir yerde saklamak isterseniz de GetTempFileNamemetotu size işletim sisteminin geçici klasörü yolu ile birlikte geçici bir dosya adı döndürecektir.
Path.GetTempFileName();
C:\Users\Administrator\AppData\Local\Temp\tmpA116.tmp
Buradaki metotlar dosya oluşturmaz sadece isim oluşturur.
Ben veri kaynağı olarak Xml kullanması severim de herkes sevmek yada bilmek zorunda değil. Xml ile yaptığım anket uygulamasını Sql ve Ado.Net kullanarak tekrar yaptım.
Veritabanı şeması aynen aşağıdaki gibi;
Uygulamada kullanılan nesneclass diyagramı;
Uygulamada kullanılan örnek kod;
public void OyVer(int AnketSoruID) { using (SqlConnection con = new SqlConnection( "Data Source=.;Initial Catalog=calismalar;Integrated Security=True;")) { using (SqlCommand com = new SqlCommand( "update AnketSorular set AnketOy += 1 where AnketSoruID = @AnketSoruID", con)) { com.Parameters.AddWithValue("@AnketSoruID", AnketSoruID); con.Open(); com.ExecuteNonQuery(); } } }
Uygulama kaynak kodları da burada. Sql script ise burada.
CheckForIllegalCrossThreadCalls = false; ve Thread güvenliği can sıkıcı olursa;
using System.Threading; using System.IO; namespace desktop { public partial class Form1 : Form { public delegate void Ekle(); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { flowLayoutPanel1.BeginInvoke(new Ekle(ResimEkle)); } void ResimEkle() { foreach (string file in Directory.GetFiles(@"D:\Pictures\aniGifs", "*.gif")) { PictureBox p = new PictureBox(); p.Width = 50; p.Height = 50; p.SizeMode = PictureBoxSizeMode.StretchImage; p.ImageLocation = file; flowLayoutPanel1.Controls.Add(p); } }
Northwind sql eğitimlerinde sıkça kullandığım (basit yapısınsan dolayı) bir veri tabanı örneğidir. Aynı zamanda eskidir de :) En sık başvuru yaptığım tablolardan biri de Categories tablosudur. Bu tabloda kategorileri resimleri ile yer almaktadır. Yer almasına alıyor da, alırken ilk 78 ve son 78 byte kısmında ole nesne bilgisi olduğu için kimi zaman sorunlar yaşanıyor. Her ne kadar DataGridView kontrolü bunu otomatik gösterse de, manuel olarak PictureBox gibi bir kontrolde göstermek istersek şu şekilde kullanmak gerekiyor.
private void Form1_Load(object sender, EventArgs e) { foreach (Category cat in CategoryProcess.GetCategories()) listBox1.Items.Add(cat); } private void button1_Click(object sender, EventArgs e) { Category cat = (Category)listBox1.SelectedItem; byte[] resim = CategoryProcess.GetPicture(cat.CategoryID); MemoryStream mem = new MemoryStream(); mem.Write(resim, 78, resim.Length - 78); pictureBox1.Image = Image.FromStream(mem); for (int i = 0; i < 78; i++) textBox1.Text += ((char)resim[i]).ToString(); }
Çok yakın ve kadim bir dostum için araştırırken farkettim ve paylaşmak istedim. ListView kontrolü içinde ki verileri gruplayarak göstermek. DataList kontrolündeki RepeatColums özelliğini kullanmak gibi fakat birazcık farklı :)
Div etiketleriyle Listview'e şablon hazırlamak yeterli.
<asp:ListView ID="Listview1" runat="server" GroupltemCount="S" EnableViewState="false"> <ItemTemplate> <div style="width: 200px; float: left; font-family: Verdana; font-size: l0px; margin-bottom: l0px;"> <asp:Image ID="Imagel" runat="server" ImageUrl='<%# "image.aspx?path=" + Eval("FullName") %>' /> <br /> <strong>Dosya Adi:</strong> <%# Eval("Name")%> <br /> <strong>Uzunluk: </strong> <%# Eval("Length")%> <br /> <strong>Özellikler : </strong> <%# Eval("Attributes")%> </div> </ItemTemplate> <LayoutTemplate> <div id="groupPlaceholderContainer" runat="server"> <div id="groupPlaceholder" runat="server"> </div> </div> </LayoutTemplate> <GroupTemplate> <div id="itemplaceholdertontainer" runat="server" style="width: l000px;"> <div id="itemPlaceholder" runat="server"> </div> </div> </GroupTemplate> </asp:ListView>
Veri kaynağı için basit ve hızlı bir çözüm, dosyalar.
Listview1.DataSource = from file in new DirectoryInfo("C:\\windows").GetFiles() orderby file.Name select new { file.Name, file.Length, file.FullName, file.Attributes }; Listview1.DataBind();
Dosyaları biraz süslü gösterelim.
string path = Request["path"]; Icon ico = Icon.ExtractAssociatedIcon(path); Bitmap bmp = new Bitmap(ico.Width, ico.Height); Graphics g = Graphics.FromImage(bmp); g.DrawIcon(ico, new Rectangle(0, 0, ico.Width, ico.Height)); bmp.Save(Response.OutputStream, ImageFormat.Png); g.Dispose(); bmp.Dispose(); ico.Dispose();
Kötü emelleri olan bir öğrencim için derste geliştirdiğimiz bir uygulama. Kısaca anlatmak gerekirse, sisteme takılacak çıkarılabilir usb flash diskleri gözlemleyip içeriğini kopyalayan basit anlamda casus yazılım :)
string directory = string.Empty; //void kopyala(string path, string name) void kopyala(object parameters) { string[] paras = (string[])parameters; directory = "c:\\depo\\" + ((paras[1] == string.Empty) ? Guid.NewGuid().ToString() : paras[1]); //kök için klaör oluştur Directory.CreateDirectory(directory); //kök içindeki tüm dosyaları kopyala foreach (string file in Directory.GetFiles(paras[0])) { try { File.Copy( file, directory + "\\" + Path.GetFileName(file), true); } catch { ;} } DirectoryInfo dif = new DirectoryInfo(paras[0]); //kök içinde klasör(ler) var ise if (dif.GetDirectories().Length > 0) copyRest(dif.GetDirectories());//hepsini kopyalayacak metotu başlat ->recursive //tüm kopyalamalar bitince dinlemeye devam t1.Abort(); timer1.Start(); }
Devamını görmek için projeyi indirebilirsiniz.
Daha önceleri MARS (Multiple Active Result Sets) uygulamalarımı Treeview yada Listbox kontrollerini kullanarak yapıyordum. Listview içinde sıralama ile uğraşırken bir örnekte bu kontrolle yapayım dedim.
//görünüm ayarlaniyor listView1.View = View.Details; listView1.FullRowSelect = true; //3 adet kolon ekleniyor listView1.Columns.Add("Product Name", 300); listView1.Columns.Add("Unit Price", 150); listView1.Columns.Add("Units In Stock", 100);
//Northwind veritabanından kategoriler ve Ürünlerler çekiliyor SqlConnection con = new SqlConnection("Data Source=. ;Initial Catalog=Northwind;Integrated Security=True;MultipleActiveResultSets=True;"); SqlCommand comCat = new SqlCommand("Select CategcrylD,CategoryName from Categories order by CategoryName", con); SqlCommand comPro = new SqlCommand("Select ProductName,UnitPrice,UnitslnStock from Products where CategorylD = @id", con); comPro.Parameters.Add("@id", SqlDbType.Int); SqlDataReader rdPro = null; con.Open(); SqlDataReader rdCat = comCat.ExecuteReader();
//verileri ekleniyor while (rdCat.Read()) { //Kategori adı grup olarak ekleniyor ListViewGroup group = new ListViewGroup(); group.Header = rdCat.GetString(1); listView1.Groups.Add(group); comPro.Parameters[0].Value = rdCat[0]; rdPro = comPro.ExecuteReader(); int rowlndex = 0; while (rdPro.Read()) { //ürünler ekleniyor ListViewItem item = new ListViewItem(); item.Text = rdPro.GetString(0); item.SubItems.Add(rdPro[1].ToString()); item.SubItems.Add(rdPro[2].ToString()); //ürünün ait olduğu kategori seçiliyor item.Group = group; //alternatif görünüm için arkaplan rengi mod ile ayarlanıyor item.BackColor = (rowlndex++ % 2) == 0 ? Color.Beige : Color.Wheat; listView1.Items.Add(item); } rdPro.Close(); } rdCat.Close(); con.Close();
Koleksiyoncollection doldurmak için başka bir alternatif:
Web siteniz için yurt dışından host hizmeti alıyorsanız, DateTime (Structure) yapısının string metotları istediğiniz sonuçları döndürmeyebilir. Bunun için örnek bir Extension Method hazırladım;
Şöyle bir düşündüğümüzde veritabınında bulunan herhangi bir tablonun verilerini Xml formatında dosyaya yazmanın kaç yolu vardır acaba? Sabahları genelde işe erken gelirim, 1.5 saat kadar :). Oturdum bir kaç örnek yaptım, paylaşıyorum tüm dünya ile. (Özgüvenin tavan yaptığı an) Aklıma gelen ilk yöntem DataTable nesnesini kullanmak. Bu nesneyi sadece yazmak için kullanmak kaynak tüketimi açısından çok iyi bir seçim olmaz fakat kullanım kolaylığı açısında tercih edilebilir.
Diğer bir yöntem ise henüz Veri KatmanındaDataLayer iken oracıkta Xml formatına dönüştürüp XmlTextWriter ile cayır cayır yazmak.
Son yöntem ise daha önce şu yazıda kullandığım teknik ile (attributenitelik yerine bu sefer nodedüğüm kullandım) XDocument ile manuel olarak Xml dosyasını oluşturmak. Sanırım en zoru bu. Yanlış anlaşılmasın benim için kolay da hani ilk yapan için diyorum :)
CloseConnection ne işe yarar neden kullanılır? Command nesnesinin executeReader metotu ile kullanılan enumnumaralandırıcı olarakta bilinir. Varsayılan değeri Default fakat ihtiyaç gereği 6 adet daha kullanılan değeri mevcuttur ki CloseConnection bunlardan biridir. Command nesnesine bağlı olan Connection nesnesi DataReader nesnesi kapatılana kadar açık kalır. Neden kalsın ki? Örnek bir kullanım ile açıklayalım; Kazancımıza bakalım; - DataReader ile okumanın DataAdapter ile okumaktan daha hızlı olduğunu herkes bilir. + 1 (Connection nesnesi kapansaydı DataReader nesnesi null olarak gelecekti. Açık bırakırsak ayrı bir dert) - SqlCommand nesnesini Program nesnesine çekersekte uygulama System.Data.SqlClient' a bağımlı kalacaktı bu da iyi bir tasarım olmayacaktı. + 2
Bir kelimenin yada sözcüğün harflerinin yerlerini değiştirerek yeni bir kelime yada sözcük elde etme durumuna Anagram denir. Yunanca bir kelime olan anagramma' dan gelir.
Örneğin, Vin Diesel -> 'I End Lives' yada Bahri -> 'İhbar' gibi.
Bu mantık ile bir uygulama yapmak istersek iki adet string dizisiarray tanımlamak gerekir;
Şimdi mantığı biraz değiştirerek ve basit bir de algoritma ile uygulamayı daha dinamik bir hale nasıl getirebiliriz ona bakalım.
Öncelikle orjinal kelimeleri ';' noktali virgül ile ayırarak text dosyasına kaydedelim. Bu sayede kelimelerimizde uygulama içinde statik olarak kalmayacak.
Dosyadaki kelimeleri bir diziye atayalım. Daha sonra basit bir metot yazarak sırası ile dizideki kelimelerin harflerini karıştırarak yeni kelimeler elde edelim. Buradaki durum anagram da olduğu gibi mantıklı değil fakat harf kaybı olmaksızın yeni kelimeler elde etmek olacak. Metot, kelimedeki harfleri değil de harflerin indexlerini karıştıracaktır. Bu sayede kelime içinde bir harfin birden fazla olması durumunda ekstra kod yazmamız gerekmeyecek.
Burada her nekadar dizi içinde tutulacak değerler tam sayı olsada ben string tipini tercih ettim. Sebebi ise, int veri türünün başlangıç değeri 0 olduğundan 0 nolu indeks değerinin kontrolünün yapılmasının kolay olmasıdır.
Kodun tamamı; anagramgame.rar Kaynak : Wikipedia
Özel bir eğitim için 2 hafta süresince C++ dili ile ilgili araştırmalar yapma fırsatım oldu. Aynı uygulamayı 3 farklı dil versiyonunda yazdım. Sonra şu soruyu sordum kendime, C# bilmek C++ öğrenmek için bir avantaj olabilir mi yada tam tersi. Sanırım cevap kodlarda gizli
Öğrencilerimin en sık sorduğu sorulardan biri de, veritabanında depolanmış resimleri web sayfasında nasıl gösterildiğidir. Internette bu konu hakkında zilyon tane yazı olmasına karşın bir tane yazma gereği hissettim.
Öncelikle anlaşılması gereken konu, html sayfalarında resim göstermenin ilk koşulu resmin fiziksel yolunun kontrole yada etikettage aktarılmasıdır. Örneğin;
Diğer taraftan baktığımızda ki bu taraf veritabanı tarafıdır, resim gibi içeriklerin hangi tip veri alanında saklanacağıdır. C# ile yazılım geliştiryorsanız resim yada bir dosya serileştiğinde (yani veritabına yazıldığında) byte dizisinden (byte[]) ibaret olacaktır. Bu durumda en uygun alan tipi varbinarybyte[] olsa iyi olur. :)
Kaçınılması gereken davranışlar.
yada
hiç olmadı :)
Peki yapılması gereken nedir? Veritabınından okunan byte dizisini resim formatında dışarı aktaracak (response) bir dosya (aspx,ashx) oluşturmak ve oluşan dosyanın yolunu resmi gösterecek kontrol yada etikete atamaktır.
Örnek tabloda gösterildiği gibi resim UrunResim alanında varbinarybyte[] olarak saklanıyor.
Resmi oluşturacak resim.aspx sayfasına gönderilen parametre değeri ile veritabanında basit bir sorgu yapılarak ve sonucu byte dizisi olarak elde edilir.
Son olarak ise sayfa çıktısının resim olacağını işaret eder ve çıktıyı BinaryWriter metotu ile oluştururuz.
Zengin içerikli elektronik postalare-mail hazırlarken en büyük sıkıntı kaynağın tekrar okunup gövdebody bilgisi olarak MailMessage nesnesine verilmesi diyebiliriz. Bu sıkıntıyı kolay bir şekilde atlatmanın yolu sanırım WebUserControl kullanmak olacaktır. Kullanalım o zaman :)
Verileri almak için kullanacağımız Stored Procedure;
E-Mail içeriğini sağlayacak olan WebUserControl;
Kontrolün toString metodunu ezerekoverride kullanım kolaylığı sağlıyoruz;
son olarak e-maili gönderecek olan kodlar;
Uygulamanın tamamı.
GZipStream kullanırken sıkışacak ve açılacak dosya hakkında bilgi tutmak için (algoritmasında var olan mantığı kullanmak için ekstra özellik ve metod olmadığından) nesne olarak tasarlayıp serileştirip yollamak mantıklı bir çözüm olabilir. önce:
Daha mantıklısı DeflateStream kullanmakmış:) sonra:
Uygulamayı indir.
VS2005 SP1 ile New Project -> Web altında gelen Web Application üzerinden uygulaması geliştiriyorsak Profile kullanımı ne yazık ki Web Site ile kullanımından çok farklı bir hal alıyor. Peki bu hal nasıl ona bakalım; Önce web.config dosyasında birkaç küçük ayar yapıyoruz;
Daha sonra ise kod kısmında. Örneğin kullanıcı kayıt sırasında değerleri eşitlemek istersek;
Kurulumsetup sırasında uygulamanın kullanacağı veritabanı bağlantı bilgisi nasıl elde edilir? Bir örnek yapalım. Önce; Setup projesinin UserInterface Editör'üne bir adet TextBoxes (A) Form u ekleyelim. Bu form üzerinde 4 adet TextBox kontrolü bulunuyor. İhtiyaç duyacağımız bilgileri almak için ideal. Daha sonra formu Installation Folder dialoğun üstüne alalım ve özellikpropertyleri resimdeki gibi eşitleyelim;
Değerleri Installation Classnesne taki metoda geçirmek için Custom Action Editör'üne Install Action ekleyelim ve CustomActionData özelliğini resimdeki gibi ayarlayalım.
Sonra; Projemize bir adet InsallerClass ekleyelim. OnAfterInstall metodunu ezipoverride gerekli kodları yazalım;
protected override void OnAfterInstall(IDictionary savedState) { string data = Context.Parameters["cs"]; string[] datas = data.Split(';'); string value = string.Format("Data Source={0};Initial Catalog=northwind;uid={1};pwd={2};", datas[0], datas[1], datas[2]); Assembly thisAss = Assembly.GetExecutingAssembly(); string path = thisAss. Location. Replace(thisAss.GetName().Name + ".exe", thisAss.GetName().Name + ".exe.config"); XmlDocument doc = new XmlDocument(); doc.Load(path); doc.SelectSingleNode("/configuration/connectionStrings/add[@name='strConn']") .Attributes["connectionString"].Value = value; doc.Save(path); base.OnAfterInstall(savedState); }
Kurulum sırasında kullanıcının belirlediği değerler, App.config dosyasındaki ConnectionString özelliğine yazılacaktır.
Eğer GDI+ kullanarak bir metni tam olarak hizalamak isterseniz;
Yazılımcı site yapar, çoklu dil desteği yapar. Birde yanına SiteMapPath olsun ister. Bu durum da SiteMapPath kontrolü için en önemli problem 2 adet .sitemap dosyasının olması ve hangisini kullanacağını bilememesidir. Bu durumu aşmanın yolu web.config dosyasına her bir sitemap için provider tanımlamaktır.
Tanımlanan providerları tarayıcının kullandığı dile göre kontrole eşitlemek işin son kısmı olacaktır.
Yerel Pc' nin Versiyon 4 Ip adresini almak.
DiziArraynin belli bir kısmını yeni bir diziye kopyalama şeysi, mp3 Tag ver.1 bilgisi almak için de örnek:
Hep yazmak istemişimdir, kısmet bu geceymiş :=)
Win Proje
Web Proje
LinqToXml ile Xml dosyası oluşturup Treeview kontrolü ile gösterelim;
Bir projede Login kontrollerinden PasswordRecovery kullanıyorum. E-mail içeriğindeki Türkçe karakterler problem oluşturuyor. Önce bu şekilde denedim.
olmadı, bende işi biraz uzattım.
mailBody.txt dosyasının içeriği;
TextBox'ın üzerine sürüklenen dosyanın yolunu almak.
Generic Classnesne oluştururken birden fazla tiptype parametesi ve herbiri için kısıtlama verilecekse anahtar kelime enter olacaktır.
Daha önce burada yapmış olduğum Anket uygulaması nasıl olurda pasta grafiği ile gösterilir dedim, böyleymiş.
Anket verilerinin bulunduğu Xml dosyası;
AjaxControlToolkit Slider için örnek düşünürken jpeg sıkıştırması gayet güzel olur dedim :)
EncoderValue Enumeration
İki tarih arasında ki hafta sonu gün sayısı kaç adettir? Aradım bulamadım, .Net Framework içinde hazır bir metod yok :(
Windows uygulamalarında klasör ve dosyaları listelemek için sıkça kullanılan TreeView kontrolünü aynı iş için Asp.Net ortamında nasıl kullanabiliriz? Web formuna ToolBox -> Navigation -> TreeView kontrolü ekleyelim ve kod tarafına geçelim. Öncelikle bir adet recursivetekrarlanan metot yazalım (System.IO eklemeye unutmayalım).
Bu metod başlangıç yolundan itibaren ne kadar klasör ve altında da ne kadar dosya varsa bitine kadar çalışacaktır. Fakat ortamın web olmasından dolayı bulunduğu Index'i bilemeyecektir. O yüzden ViewState tabanlı bir Propertyözellik yazalım.
Başlangıç noktasındaki dosyalar listeleniyor.
Kodu başlatıyoruz.
İşte sonuç.
Projei indir.
GridView kontrolü içinde Tooltip kullanımı için bir alternatif. Tooltip olarak gösterilecek alanı DataKeyNames içinde saklayıp uygun kolona Attributenitelik ile eşleştirmek.
Bir uygulama düşünün ki veriler Xml dosyasında sunum ise WebForm' unda olsun.
İşte tam aradığımız kontrol;
Verileri Xml dosyasında saklamının avantajlarından birisi de Xslt ile web uygulamalarına kolayca adapte edilebilmesidir. Örnek Xml verisi için Xslt kodu;
sonuç;
Proje kodları.
Windows uygulamalarında sıkça kullandığımız MessageBox.Show() birkaç adım ile WebForm'larında kullanılabiliyormuş.
Şöyle ki; Öncelikle projemize System.Windows.Forms Namespace'ini ekliyoruz. Daha sonra da aşağıdaki kodları yazıyoruz.
pek mantıklı değil:)
Bazen Asp.Net sayfalarımızın clientistemci tarafında durum gereği farklı davranmasını isteyebiliriz. Tabiki JavaScript kodlarını devreye sokarak. .NET Framework 2.0 versiyonu ile bunu yapmanın yolu ClientScriptManager Classnesne ının RegisterStartupScript metodunu kullanmak olacaktır. Bilindiği gibi RegisterStartupScript metodu 1.1 versiyonuda da bulunmaktaydı. Birçok metod gibi 2.0 ile bunun da kullanımı biraz değişmiş :) Uygulamamızda; clientistemci tarafında window.open( [sURL] [, sName] [, sFeatures] [, bReplace]) metodunu kod tarafında ise public void RegisterClientScriptBlock ( Type type, string key, string script ) metodunu kullanacağız.