Visual Studio Word 2010 Document Projesi

Bazı zamanlarda programımızda bir word çıktısı ihtiyacı kaçınılmazdır. Ancak her zaman müşterimizin spesifik çıktı işlemleri için programımıza bir word yada excel export eklememiz gerekmeyebilir. Konuyu şöyle anlatacak olursak, örneğin elinizde çalışan büyük bir programınız var ve yüzlerce kullanıcı bu programı kullanmakta. Ancak A departmanı gelip sizden programa ait verileri içeren bir adet word çıktısı isteyebilir. Bu durumda ilk akla gelen programın A departmanı ile ilgili arayüzüne yeni bir sayfa yada form ekleyip kullanıcının isteğini gerçekleştirmek. Ancak bu hem zaman alır, hemde çalışan programa müdahale etme gereksinimi doğurur. Deployment yapmadan önce daha detaylı testler gerektirir vs vs.

Diğer bir yöntem ise önceden hazırlanmış belirli bir word dökümanına eklenti yazmak olabilir. Bunun için visual studio bize oldukça kolay kullanımlı araçlar sunuyor.

İsterseniz benim de daha önce çalıştığım bir kurumda karşılaştığım bir ihtiyaç üzerinden bir örnekle devam edelim. Gerçek hayat örnekleri bence her zaman daha kolay anlaşılıyor 🙂

Çalıştığım kurumun binlerce kredi müşterisi bulunmaktaydı ve kredi ödemelerini takip eden departmandan şöyle bir istek geldi. “Bizim elimizde müşterilere gecikme durumunda idari takip olacağını belirten sabit formatta bir word dokumanımız var ve programın ekranından müşteri bilgilerine bakarak belli gün gecikmesi olan müşterilere mektup hazırlıyoruz ve gönderiyoruz. Ancak bu çok vaktimizi alıyor. Çözüm üretir misiniz?” İstek bu şekildeydi. Ofisin içinde yer alan adres mektup birleştirme yöntemini kullanarak çözemiyorlardı çünkü istemiş oldukları bilgiler bir excel yada access listesinde değildi. Ancak geliştirici olarak ben de müşteri takip programımıza müdahale etmek istemiyordum. Gelin şimdi bunun için bir çözüm üretelim.

İlk önce Visual Studio’nuzda bir adet Office Word Document Projesi oluşturunuz.

Office Word Project

Ben projeye “GecikmeMektubuApp” adını verdim.

Daha sonra ekranda size Yeni Bir Word dokümanı mı oluşturmak istiyorsunuz yoksa mevcut bir tanesini mi seçmek istiyorsunuz diye soracak. Senaryo gereği zaten ilgili departman mektubu önceden hazırladığı için ben yeni bir döküman oluşturmuyorum.

wordProject_2

Ok’e bastıktan sonra dikkat ederseniz Visual Studio içerisinde Office Word açıldı. Bu pek alışık olmadığımız durum bize çok büyük kolaylık sağlamakta. Seçmiş olduğum mektubun metni de aynen ekranda yer almakta. Solution Explorer’a bakarsanız bir adet docx (muhtemelen seçtiğiniz döküman isminde) ve bu docx dosyası altında yer alan “ThisDocument.cs” dosyasını göreceksiniz. ThisDocument.cs mevcut dökümanınızla ilgili global işlemleri yapmanıza yaracak.

Aşağıdaki ekranda görüneceği üzere ben mektubumda değişken olacak yerleri belirledim. Şimdi burda önemli nokta sadece benim değişkenleri belirlemem değil bunların değişken olacağını programıma da söylemem. Bunun için değişken olacak kelime yada kelime grubunu seçin ve daha sonra Toolbox’ınızda yer alan “Word Controls” grubu içinden “Bookmark” tutup seçili kelime grubunuz üzerine sürükleyin. Çıkan bilgilendirme mesajına ok diyip kapatın. Şu anda sayfamızın içine bir adet bookmark koyduk ve muhtemelen adı “bookmark1” gibi bir şey olmalı. Bookmarkınızın üzerine imleci koyup visiual studio’da yer alan properties pencerisine bakacak olursanız bookmark adını görebilirsiniz. Bunu anlamlı bir isimle değiştirin. Örneğin “bmMusteriAdi” gibi.

wordProject_3

Bütün değişkenlere bookmark koyduysanız artık word dökümanımızla işlemimiz bitti ve bir arama ekranı tasarlamamız gerekmektedir. Arama ekranında çalışan gecikme gün sayısını girecek ve girdiği sayıya eşit ve büyük olan sonuçları ekrana getirecek. Peki word içerisinde kendimize ait bir pencere nasıl oluşturacağız.

Bunun için Solution Explorer’da projenizi sağ tıklayıp Add >> New Item diyerek yeni bir Action Pane Control ekleyin.  Ben ismine “apCreditSearch” dedim. Dikkat ederseniz action pane windows form uygulamalarında yer alan user control gibi düz, pencere kontrolleri olmayan bir panel gibi görünüyor. Bunun içine ben bir adet textbox, bir adet button ve bir adat datagridview kontrolü koydum ve ekran aşağıdaki gibi oldu.

wordProject_4

Bu bizim arama ekranımız ve artık c# kodları yazabiliriz. İki adet event’im var. Birincisi tabiki Button Click eventi diğeri ise grid view’e ait selection change eventi. Örnek uygulama olduğu için verileri mi bir veri tabanı yerine bir listeden çektim. O yüzden action pane control’üm ilk oluşturulduğunda veri listemi dolduruyorum. Action Pane’e ait kodlar aşağıdaki gibidir.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace GecikmeMektubuApp
{
    partial class apCreditSearch : UserControl
    {
        //Data kaynağım
        List<KrediBilgisi> datalar = new List<KrediBilgisi>();
        public apCreditSearch()
        {
            InitializeComponent();
            //Daya kaynağımı dolduruyorum.
            DataListesiniDoldur();
        }
        private void btnBul_Click(object sender, EventArgs e)
        {
            //Ara butonu ile arama işlemini yapıyor ve grid kontrolümü dolduruyorum.
            grdResult.DataSource = DatalariGetir(Convert.ToInt16(txtGun.Text));
            grdResult.Columns[2].Visible = false;
            grdResult.Columns[4].Visible = false;
            grdResult.Columns[5].Visible = false;
        }

        //Data kaynağını gecikme gün sayısına göre filtreliyorum.
        public List<KrediBilgisi> DatalariGetir(int gecikmeGunSayisi)
        {
            return datalar.Where(x => x.GecikmeGun >= gecikmeGunSayisi).ToList();
        }
        public void DataListesiniDoldur()
        {
            for (int i = 0; i < 15; i++)
            {
                KrediBilgisi item = new KrediBilgisi()
                {
                    GecikmeGun = i,
                    KrediNo = 8234596 + i,
                    KrediTutari = 12 * i,
                    Musteri = "Deneme Müşterisi_" + i.ToString(),
                    OdemeGunu = DateTime.Today.AddMonths(-i),
                    TaksitNo = i
                };
                datalar.Add(item);
            }
        }
        private void grdResult_SelectionChanged(object sender, EventArgs e)
        {
            if (grdResult.SelectedRows.Count > 0)
            {
                KrediBilgisi seciliKredi = (KrediBilgisi)grdResult.SelectedRows[0].DataBoundItem;

                //Dokümanıma koymuş olduğum bookmark'ları güncelliyorum.
                Globals.ThisDocument.bmGecikmeGun.Text = seciliKredi.GecikmeGun.ToString();
                Globals.ThisDocument.bmKrediNo.Text = seciliKredi.KrediNo.ToString();
                Globals.ThisDocument.bmKrediTutari.Text = seciliKredi.KrediTutari.ToString("f2");
                Globals.ThisDocument.bmMusteriAdi.Text = seciliKredi.Musteri;
                Globals.ThisDocument.bmTaksitNo.Text = seciliKredi.TaksitNo.ToString();
                Globals.ThisDocument.bmTaksitTarihi.Text = seciliKredi.OdemeGunu.ToShortDateString();

            }
        }
    }
    //Örnek nesnem
    public class KrediBilgisi
    {
        public string Musteri { get; set; }
        public int KrediNo { get; set; }
        public decimal KrediTutari { get; set; }
        public int GecikmeGun { get; set; }
        public int TaksitNo { get; set; }
        public DateTime OdemeGunu { get; set; }

    }
}

Artık arama işlemi de bitti. Burada dikkat edilmesi gereken husus Action Pane Control’ümden word dökümanı içerisinde yerleştirmiş olduğum bir bookmark’a erişme şekli. Dikkat ederseniz Globals.ThisDocument diyerek thisdocument içerisinde yer alan nesnelere erişebiliyorum.

Şimdi sadece yapmamız gereken bu word dokümanı çalıştığında ekranda Action Pane Control’ümüzü göstermek bunun için ThisDocument.cs de yer alan “ThisDocument_Startup” olayını kullanıyoruz. Adından da anlaşılacağı üzere word dokümanı ilk çalıştırıldığı zaman bu olay çalışacak.

ThisDocument.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using Microsoft.Office.Tools.Word;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Office = Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;

namespace GecikmeMektubuApp
{
    public partial class ThisDocument
    {
        //ActionPane kontrolümüzün bir örneğini oluşturuyoruz.
        private apCreditSearch apSearch = new apCreditSearch();
        private void ThisDocument_Startup(object sender, System.EventArgs e)
        {
            //Ekranda ActionPane kontrolümüzü gösteriyoruz.
            this.ActionsPane.Controls.Add(apSearch);
        }
        private void ThisDocument_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisDocument_Startup);
            this.Shutdown += new System.EventHandler(ThisDocument_Shutdown);
        }

        #endregion
    }
}

Uygulamamız bitti ve çalıştırdığımızda aşağıdaki gibi bir ekran görünecektir. İlk başta tabiki gridview boş olacak kullanıcı arama bölümüne bir sayı girdiğinde grid dolacak ve grid’de herhangi bir kişiyi seçtiğinde mektup güncellenecek.

wordProject_5

Eğer Solition Explorerda projenizi sağ tıklayıp Publish ederseniz bir adet setup dosyası ve bir adet word dokümanı oluşturacak. Kullanıcı bilgisayarına setup dosyasını kurmasanız bile word dokümanını çalıştırdığınız ilk seferde gerekli kurulumları otomatik yapacak. Sonra kullanıcının her mektup üretmek istediğinde sadece elindeki word dokümanını çalıştırması yeterli olacaktır.

Böylece ayrı bir uygulama yazmadan, mevcut uygulamamıza dokunmadan kullanıcı isteğini gerçekleştirmiş olduk.

Proje doyası: http://yadi.sk/d/eOxwODIwAFpRj

Herkes İyi Çalışmalar,

Linq – ConvertALL Methodu

Convert all methodunu hızlıca tanımlayacak olursak elimizde bulunan ve T tipinde nesneler içeren bir Generic List’i hızlıca P tipi içeren başka bir Generic Liste dönüştürme işlemini gerçekleştirir diyebiliriz.

Ee yani ne işe yaracak diyebilirsiniz. Örneğin MVC kullanan arkadaşlarda benim gibi mi yapıyor tabi bilmiyorum ama ben sıklıkla şöyle bir senaryo ile karşılaşıyorum: Elimde bir dizi veri tabanından gelmiş kayıt var. Genelde Entity Framework veya nHibernate kullandığım için elimdeki bu kayıtlar bir datarow yada datatable değil de entity nesnesi içeren listeler oluyor. Yani List<Kitap> gibi bir listeyi veri tabanından almış oluyorum. Daha sonra bunu ekranda göstermek için action içinde bir model tanımlıyorum. Aslında List<Kitap> nesnemde tabiki bir model ve ben bunu sayfada kullanabilirim. Ancak kitap nesnesinin bir çok property’si var ve ben ekranda bunlarda sadece bir ikisini göstereceğim. O zaman koca bir nesneyle çalışmak istemiyorum ve bir adet ViewModel oluşturuyorum. Yani sonuçta elimde içi dolu bir List<Kitap> diye bir nesne var ve List<KitapViewModel> diye boş bir liste oluyor.  Bir taraftaki verileri diğer tarafa aktarmam gerekiyor.

Tabi en akla gelen metod birinci liste içinde foreach ile dönüp ikinci listeyi doldurmak. Oysaki bu işlemi birden fazla yerde yapıyorsak uzun ve can sıkıcı olabilir.

Bu benim sıklıkla yaşadığım bir senaryo ama kod yazarken çoğu zaman farklı türleri dönüştürme işlemi ihtiyacı muhakkak çıkıyor. O yüzden ConvertAll() bize büyük kolaylık sağlıyor.

Hemen bir örnek yapacak olursak. Yukarıda da bahsettiğim gibi elimizde veritabanından yada başka bir yerden bir şekilde dolmuş bir generic listemiz var ve bu liste KitapEntity tipinde nesneler içeriyor ve ben bunu KitapViewModel içerecek şekilde tekrar düzenlemek istiyorum. Aşağıdaki kod yeterli olacaktır.


using System;
using System.Collections.Generic;

namespace ConvertAllLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            //Siz burada bu kitapların veritabanından geldiğini düşünebilirsiniz. Ben şimdilik elle listemi dolduruyorum
            List<KitapEntity> kitaplar = new List<KitapEntity>();

            kitaplar.Add(new KitapEntity() { Baski = 1, Id = 1, KitapAdi = "Steve Jobs", YayinEvi = "ABC", Yazar = "Walter Isaacson", Yil = 2012 });
            kitaplar.Add(new KitapEntity() { Baski = 1, Id = 1, KitapAdi = "Doktor Uyku", YayinEvi = "Altın Kitaplar", Yazar = "Stephen King", Yil = 2012 });

            //Liste içindeki kitapları ekrana yazdırıyoruz.
            foreach (KitapEntity kitap in kitaplar)
            {
                Console.WriteLine(kitap.KitapAdi);
            }

            //ConvertAll methodu ile yeni listemizi oluşturuyoruz.
            //Burada dikkat edilmesi gereken kısım, delegate tanımlar gibi yeni bir methodu Converter içerisine geçiyoruz.
            List<KitapViewModel> kitaplarViewModels = kitaplar.ConvertAll(new Converter<KitapEntity, KitapViewModel>(EntityToViewModel));

            //Ekrana yeni listemizin içeriğini yazdırıyoruz.
            Console.WriteLine();
            foreach (KitapViewModel kitap in kitaplarViewModels)
            {
                Console.WriteLine(kitap.KitapIsmi);
            }
        }

        //Convert işlemini yapan yardımcı methodumuz.
        public static KitapViewModel EntityToViewModel(KitapEntity entity)
        {
            return new KitapViewModel{ Id = entity.Id, KitapIsmi = entity.KitapAdi };
        }
    }

    //Veri Tabanı Nesnemiz
    class KitapEntity
    {
        public int Id { get; set; }
        public String KitapAdi { get; set; }
        public String YayinEvi { get; set; }
        public int Yil { get; set; }
        public int Baski { get; set; }
        public String Yazar { get; set; }
    }

    //Sayfada göstereceğimiz model nesnemiz
    class KitapViewModel
    {
        public int Id { get; set; }
        public string KitapIsmi { get; set; }
    }
}

Turkcell’den Mobil Uygulama Eğitimi – Geleceği Yazanlar

Türkcellden güzel bir siteyi paylaşmak istiyorum sizlerle. Geleceği Yazanlar. Android, IOS, Windows Phone ve Turkcell API hakkında güzel yazıların olduğu bir site. Daha doğrusu bir sosyal sorumluluk projesi. Sitede toplam 1200 sayfa eğitim ve 13000 satır kod bulunmakta. Tabi bunların dışında örnek uygulamalar ve videolarda mevcut. Bence bizler için çok sevindirici bir haber.

Adres: https://gelecegiyazanlar.turkcell.com.tr

Image

Herkese İyi Çalışmalar,

Melih KORKMAZ

Spotify Artık Türkiyede..

spotify

En nihayetinde bir süredir takip ettiğim Spotify Türkiye lansmanını yaptı ve Türkiye’den artık üye kayıtlarına başladı. Ve artık yurtdışı proxy ile üye olmak zorunda kalmayacağız 🙂 Neyse bilmeyenler için kısaca bahsedeyim, Spotify hem masaüstünde hem de mobilde yasal müzik dinlemeyi oldukça kolaylaştırıyor. Şu an için dünya çapında 24 milyonu aşkın üyesi var ve 300 bin’e yakın plak şirketiyle anlaşmış durumda. Ülkemizde de dünyada olduğu gibi 3 tip üyelik sunmakta. Bunlardan birincisi tabiki ücretsiz üyelik.  Unlimeted üyelik ise aylık sadece 5 TL. Birde her platformda müzik dinlemek isteyenler için aylık 10 TL olan Premium üyelik var.

Spotify uygulamasının diğer müzik platformlarından ayrılan en güzel yanı bence daha sosyal olması. Çevrenizdekiler ne dinliyor, neler popüler vs. gibi birçok kullanışlı özelliği var.

Sonuç olarak benim gibi çalışırken bir yandan müzik dinleyen arkadaşlar için oldukça kullanışlı.

Herkese İyi Çalışmalar,

Melih KORKMAZ

Windows 8.1 ve 3D Printing Özelliği

3D Printing konusu aslında 1980’li yılların başından beridir geliştirilmekte ve uygulanmakta. Ancak bence popülerliğini kendi evine alabileceğiniz maliyette ve büyüklükte printir’lar çıktıktan sonra arttırdı. Tabi teknolojinin gelişimiyle birlikte hızlı bir büyüme doğaldır ve bu yüzden 2012 yılında dünya çapında 2.2 milyar dolarlık bir pazara eriştiği de söylentiler arasında.

Neyse benim bahsetmek istediğim ise bu konuya Microsoft tarafınında kaygısız kalmaması ve Windows 8.1’e 3D printer özelliğini eklemesi. Aşağıdaki videodan daha detaylı bir şekilde görebilirsiniz. Bizim evlerimize ne zaman girer bilemiyorum ama oldukça eğlenceli görünüyor 🙂

Herkese İyi Çalışmalar,
Melih KORKMAZ

C# ve Tuple Sınıfı

Tuple sınıfı C# 4.0 ile hayatımıza girmiş ve bence çok kullanışlı, nevi şahsına münhasır tuhaf bir arkadaştır kendisi. Tuple sınıfı birden çok Item’a sahiptir ve her Item’ın kendi tipi vardır. Eee ne demek yani bu diyebilirsiniz. Ben bunu çalışma anında dinamik bir sınıf oluşturmaya benzetiyorum. Yani bir Tuple sınıfının örneğini alıyorsunuz ve buna property gibi(tabi property değildir) değişik tipte Item’lar ekleyebiliyorsunuz ve daha sonra bu item’lardan istediğinizi kullanabiliyorsunuz.

Sanırım iyice çorba ettim ve ben en iyisi örnek kodu paylaşayım 🙂

namespace TupleOrnek
{
    class Program
    {
        static void Main(string[] args)
        {
            Tuple<int, string> tupleOrnek_1 = Tuple.Create<int, string>(5, "A");

            Tuple<int, string, Profil> tupleOrnek_2 = Tuple.Create<int, string, Profil>
                (5, "B", new Profil { Ad="Saim", Soyad="Lazlıçeşme" });

            Tuple<int, string, Profil, Araba> tupleOrnek_3 = Tuple.Create<int, string, Profil, Araba>
                (5, "C", new Profil { Ad = "Saim", Soyad = "Lazlıçeşme" }, new Araba { Marka = "Opel", Model = "Insignia" });
            
            //Artık 3 adet tuple sınıfımız var içerdiği bilgileri istediğimiz gibi kullanabiliriz.

            //Son Tuple sınıfının içerdiği araç bilgisi
            Console.WriteLine(tupleOrnek_3.Item4.Marka);

            //İkinci Tuple sınıfının içerdiği kullanıcı bilgisi
            Console.WriteLine(tupleOrnek_2.Item3.Ad + " " + tupleOrnek_2.Item3.Soyad);

        }
    }
    class Profil
    {
        public string Ad { get; set; }
        public string Soyad { get; set; }
    }
    class Araba
    {
        public string Marka { get; set; }
        public string Model { get; set; }
    }
}

Böylece isterseniz Generic Listleri(IList), Dictionary(IDictionary) gibi ancak sadece TKey ve TValue’dan ibaret olmayacak şekilde kullanabilirsiniz.

Umarım bir gün bir yerde böyle bir ihtiyacınız olduğunda bu ufak ipucunu hatırlayabilirsiniz 🙂

Herkese İyi Çalışmalar,
Melih KORKMAZ

Linq – Take – Skip Kullanımı (Paging)

Generic Lists ve Linq sorguları son yıllarda iyice hayatımıza girdi. Özellikle linq kullanım kolaylığı ve verdiği sonuçlar bakımından oldukça tercih edilmektedir. Peki linq kullanırken hangi özelliklerinden yararlanıyoruz? Birçoğumuz -bende dahil- özellikle where, select gibi methodlarını kullanıyoruz. Oysa ki linq derya deniz…

Hızlıca size Take ve Skip özelliğinden bahsetmek istiyorum. Özellikle sayfalama yaparken verinin düzenlenmesinde ve gruplara ayrılmasında oldukça yardımcı oluyor.

Take: Elinizde bulunan bir liste yada IQueryable sorgusu içerisinde yer alan kayıtlardan sadece sizin belirtiğiniz sayıda kaydı getirir.

Skip: Yine Take methoduna benzer şekilde bir liste yada IQueryable sorgusu içerisinden yer kayıtlardan kaçtanesi atlayıp, kaçıncı kayıttan itibaren veriyi getireceğini belirler.

Bu arada yeri gelmişken bir generic list ve IQueryable arasında temel farktan hızlıca bahsedeyim. Örneğin Entity Framework kullanıyorsunuz ve “Users” tablosundan bazı kayıtları ekrana getirmeye çalışıyorsunuz.


var liste_1 = (from u in ent.Users
               orderby u.Id
               select u).Take(10);

Burada liste_1 tipiniz IQueryable<User> tipindedir. Bu şu demek oluyor. “Programınız buraya geldiğinde ve bu kod bloğu çalıştığında henüz program SQL’e bağlanıp verileri getirmedi.” Yani henüz bir sorgu yapmadınız. Ta ki siz liste_1.ToList() diyene kadar. ToList() dediğiniz anda eğer SQL Profiler’ınızı çalıştırıp durumu gözlerseniz “SELECT top 10 * from dbo.users” sorgusunun bir benzeri ile karşılaşırsınız. Yani IQueryable tipinde nesnelerimiz her an veri tabanından veri alabilecek şekilde hazır beklerler. Siz programın her hangi bir yerinde ToList(), Count() vb dediğiniz zaman elinde bulunan sorgu cümlesini çalıştırır ve veri tabanına gidip gelir.

Kullanıcıların sıklıkla yaptığı bir yanlış ise, hazırlamış olduğu bir method’dan önce sorguyu çalıştırıp daha sonra Take(10) yapmasıdır. Aşağıdaki gibi.

        public List<User> GetTop10()
        {
            return GetUsers().Take(10).ToList();
        }

        private List<User> GetUsers()
        {
            List<User> list = new List<User>();
            using (DBEntities ent = new DBEntities())
            {
                list = (from p in ent.Users
                        select p).ToList();
            }
            return list;
        }

Programınızı bu şekilde tasarlayıp çalıştırdığınızda ise önce veritabanından bütün veriler çekilir “SELECT * FROM dbo.Users”. Sonra elinizde bulunan bir liste içerisinden sadece 10 tanesi geri döndürülür. Tabiki bu performans açısında ve yük açısından hiç iyi olmaz.

Tekrar gelelim Take ve Skip konusuna. Yukarıda da gördüğünüz üzere Take methodunu ister veri tabanı sorgumuz için istersekte elimizde daha önceden bulunan (örnek olarak bir excel import etmişizdir ve elimizde bir generic list vardır) bir listeden istediğimiz miktarda kayıt almak için kullanırız.

“Skip” ise belirli bir sayıda kayıdı atlamamıza yarar demiştik. Örneğin 15. kayıttan itibaren 10 kaydı ekrana getirmek istediğimizde aşağıdaki gibi bir sorgu yapmamız yeterlidir.

public List<User> GetSomeUser()
        {
            List<User> list = new List<User>();
            using (DBEntities ent = new DBEntities())
            {
                list = (from p in ent.Users
                        select p).Skip(15).Take(10).ToList();
            }
            return list;
        }

Tahmin edeceğiniz üzere bunu sayfalama işlemlerinde oldukça kolay bir şekilde kullanabiliriz. Take ve Skip sayılarını parametrik olarak kabul eden bir method yazar her sayfa için o methodu farklı parametrelerle çağırabiliriz.


class Program
    {
        static void Main(string[] args)
        {
            //Sayfa 1;
            List<User> list_1 = GetSomeUser(0, 10);

            //Sayfa 2;
            List<User> list_2 = GetSomeUser(10, 10);

            //Sayfa 3;
            List<User> list_3 = GetSomeUser(20, 10);
        }
        public List<User> GetSomeUser(int skip, int take)
        {
            List<User> list = new List<User>();

            using (DBEntities ent = new BEntities())
            {
                list = (from p in ent.Users
                        select p).Skip(15).Take(10).ToList();
            }
            return list;
        }
    }

Herkese İyi Çalışmalar,
Melih KORKMAZ

WPF Formlar İçin Metro Arayüz

Biz yazılımcılar bu grafik ve görsellik işinden çektiğimiz kadar hiç bişeyden çekmemişizdir sanırım. Zaten internet çıktı mertlik bozuldu 🙂 heleki bu css gelişti, html 5 falan birde mobil arayüzler girdi aman aman. Unutmadan tabi birde browser uyumluluğu var. Neyse sonuç olarak şirketlerde grafikerler, tasarımcılar olsa bile bazı zamanlarda görsel tasarıma girmek zorunda kalıyoruz.

WinForm uygulamalar yaparken işimiz biraz daha kolaydı. 3rd part toollar kullanmadığımız sürece, “bunda görsel bu kadar oluyor abicim” diyerek işten yırtabiliyorduk. Taaa ki WPF çıkana. Tabiki WPF sadece görsel güzelliği için yapılmadı, ama görselliğin çok esnek olduğu yadsınamaz.

Neyse benim gibi bazı arkadaşlar için bir arayüzden bahsedeceğim. Esas konu bu. Adı MahApps.Metro. “Adamlar yapmış ya”, dedirtecek cinsten bence kullanımı kolay, görselliği sade ve güzel.

Hızlıca nasıl kullanacağımızdan bahsedeyim. Öncellikle Visual Studio ile Framework 4.0 platformunda bir WPF projesi oluşturalım.  Daha sonra Visual Studio içerisinde yer alan (VS’nin eski versiyonlarında Nuget için eklenti gerekebilir) Nuget için Package Manager Console’u açalım ve “Install-Package MahApps.Metro” yazarak gerekli kurulumu gerçekleştirelim.

metro_1

Daha sonra projemizin ana penceresi olan. “MainWindow.xaml.cs” sınıfını açalım. Göreceğiniz üzere MainWindow sınıfı “System.Windows.Window” sınıfından türetilmiştir. Bunu silelim ve yerine “MetroWindow” yazarak penceremizi artık MetroWindow’dan türetelim. Tabiki bunu yapabilmeniz için sınıfın en üst kısmında yer alan using bölümüne “using MahApps.Metro.Controls” yazmamız gerekecektir.

using MahApps.Metro.Controls;

namespace MahAppsMetro
{
    ///
    /// Interaction logic for MainWindow.xaml
    ///
    public partial class MainWindow : MetroWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

XAML penceremize yeni namespace’imizi belirtmemiz gerekecektir. Bunun içinse MainWindow.xaml’i açıp en üstünde yer alan <Window> bölümüne xmlns:Controls=”clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro” eklemeniz gerekmektedir.

Daha sonra “<Window >” yazan başlangıç ve bitiş tag’ını “Controls:MetroWindow” şeklinde değiştirmemiz gerekiyor.

Son olarak ise görsellerimiz için kaynakları belirmemiz gerekecektir. Resource satırlarını da yazınca XML kodumuzun aşağıdaki gibi görünmesi gerekir.

<Controls:MetroWindow x:Class="MahAppsMetro.MainWindow"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colours.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid/>
</Controls:MetroWindow>

Ana pencerenize toolbox aracılığı ile bir kaç textbox,button vb. kontrolleri ekleyerek görselinizi test edebilirsiniz.

Ben örnek olarak aşağıda yer alan windows penceresini tasarladım.

metro_2

Umarım sizinde işinize yarar.

İyi Çalışmalar,

C# Excel Export İşlemi

Eminim ki bir çoğumuz Excel’den data okuma ve elimizdeki datayı excel dosyasına çıkarma gereksinimi ile karşılaşmışızdır. Bunun için bir çok yöntem varken bence özellikle excel dosyasına veri aktarma işlemi(export) asp.net uygulamalarında oldukça kolayken windows form uygulamalarında yada wpf’de biraz daha zor olmaktadır. Çünkü asp.net uygulamalarında elimizde html stringini hızlı bir şekilde response nesnesini kullanarak excel, word vs. dosyalara aktarabiliyoruz.

Aşağıda görmüş olduğunuz sınıfla elimizde bulunan her hangi bir Generic List’i excel’e kolayca aktarabiliyoruz. Bunun için yapmanız gereken sadece uygulamanıza Microsoft.Office.Interop.Excel’i refere etmek.

Excel export sınıfı:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;
namespace ExcelExport
{
    public class ExportToExcelFile<T, U>
        where T : class
        where U : List<T>
    {
        public List<T> dataToPrint;
        // Excel object references.
        private Microsoft.Office.Interop.Excel.Application _excelApp = null;
        private Microsoft.Office.Interop.Excel.Workbooks _books = null;
        private Microsoft.Office.Interop.Excel._Workbook _book = null;
        private Microsoft.Office.Interop.Excel.Sheets _sheets = null;
        private Microsoft.Office.Interop.Excel._Worksheet _sheet = null;
        private Microsoft.Office.Interop.Excel.Range _range = null;
        private Microsoft.Office.Interop.Excel.Font _font = null;
        private object _optionalValue = Missing.Value;

        public void GenerateReport()
        {
            try
            {
                if (dataToPrint != null)
                {
                    if (dataToPrint.Count != 0)
                    {
                        CreateExcelRef();
                        FillSheet();
                        OpenReport();
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Rapor hazırlanırken hata oluştu...");
            }
            finally
            {
                ReleaseObject(_sheet);
                ReleaseObject(_sheets);
                ReleaseObject(_book);
                ReleaseObject(_books);
                ReleaseObject(_excelApp);
            }
        }
        private void OpenReport()
        {
            _excelApp.Visible = true;
        }
        private void FillSheet()
        {
            object[] header = CreateHeader();
            WriteData(header);
        }
        private void WriteData(object[] header)
        {
            object[,] objData = new object[dataToPrint.Count, header.Length];
            for (int j = 0; j < dataToPrint.Count; j++)
            {
                var item = dataToPrint[j];
                for (int i = 0; i < header.Length; i++)
                {
                    var y = typeof(T).InvokeMember
            (header[i].ToString(), BindingFlags.GetProperty, null, item, null);
                    objData[j, i] = (y == null) ? "" : y.ToString();
                }
            }
            AddExcelRows("A2", dataToPrint.Count, header.Length, objData);
            AutoFitColumns("A1", dataToPrint.Count + 1, header.Length);
        }
        private void AutoFitColumns(string startRange, int rowCount, int colCount)
        {
            _range = _sheet.get_Range(startRange, _optionalValue);
            _range = _range.get_Resize(rowCount, colCount);
            _range.Columns.AutoFit();
        }
        private object[] CreateHeader()
        {
            PropertyInfo[] headerInfo = typeof(T).GetProperties();
            List<object> objHeaders = new List<object>();
            for (int n = 0; n < headerInfo.Length; n++)
            {
                objHeaders.Add(headerInfo[n].Name);
            }
            var headerToAdd = objHeaders.ToArray();
            AddExcelRows("A1", 1, headerToAdd.Length, headerToAdd);
            SetHeaderStyle();

            return headerToAdd;
        }
        private void SetHeaderStyle()
        {
            _font = _range.Font;
            _font.Bold = true;
        }
        private void AddExcelRows(string startRange, int rowCount, int colCount, object values)
        {
            _range = _sheet.get_Range(startRange, _optionalValue);
            _range = _range.get_Resize(rowCount, colCount);
            _range.set_Value(_optionalValue, values);
        }
        private void CreateExcelRef()
        {
            _excelApp = new Microsoft.Office.Interop.Excel.Application();
            _books = (Microsoft.Office.Interop.Excel.Workbooks)_excelApp.Workbooks;
            _book = (Microsoft.Office.Interop.Excel._Workbook)(_books.Add(_optionalValue));
            _sheets = (Microsoft.Office.Interop.Excel.Sheets)_book.Worksheets;
            _sheet = (Microsoft.Office.Interop.Excel._Worksheet)(_sheets.get_Item(1));
        }
        private void ReleaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show(ex.Message.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }
    }
}

Gerekli referansları ve yukarıda yer alan sınıfı uygulamanıza eklediten sonra yapmanız gereken sadece aşağıdaki gibidir.

Örnek uygulama:

using System.Collections.Generic;

namespace ExcelExport
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Araba> dataList = new List<Araba>();

            dataList.Add(new Araba
            {
                 Marka = "Fiat",
                  Model = "Punto Evo",
                   Renk = "Siyah"
            });

            dataList.Add(new Araba
            {
                Marka = "Opel",
                Model = "Corsa",
                Renk = "Kırmızı"
            });

            ExportToExcelFile<Araba, List<Araba>> excelExport = new ExportToExcelFile<Araba, List<Araba>>();
            excelExport.dataToPrint = dataList;
            excelExport.GenerateReport();
        }
    }
    public class Araba
    {
        public string Marka { get; set; }
        public string Model { get; set; }
        public string Renk { get; set; }
    }
}

Ben sıklıkla bu yöntemi kullanıyorum. Umarım sizinde işinize yarar.

İyi çalışmalar.

Örnek Uygulama: http://yadi.sk/d/7chECprG9XRzh

XML to Database – Entity Framework Code First

Merhaba bu görselde karmaşık xml yapılarının nasıl hızlı bir şekilde c# nesnesine dönüştürülebileceğini, ve Entity Framework(Code First) yapısıyla, otomatik olarak nasıl veritabanı tablolarının hazırlanabileceğini anlattım. Umarım faydalı olur.