GridView ile çalışmak ve püf noktaları

Uzun bir aradan sonra kontrollerimizi tanımaya kaldığımız yerden devam ediyoruz. Ana hatlarıyla anlatmaya çalışacağım kontrol namı diğer GridView1 :) Çok fazla detaya girmeden en sık kullanılan özelliklerini ve jQuery ile birlikte neler yapabileceğimize vakit kaybetmeden bir göz atalım.

GridView, bir veri kaynağından gelen veriyi ekrana liste şeklinde basan kontrolümüz. Bir çok yerde kullandığımız bu kontrolde, sayfalama ve sıralama işlemlerini rahatlıkla yapabiliyoruz.

Kontrolümüzü <asp:GridView runat=”server” ID=”GridView1″></asp:GridView> şeklinde ekliyoruz.

Gridimizi şekillendirmek için ana hatlara sitil tanımlaması yapabiliyoruz. Nedir bu ana hatlar, header, row, footer ve pagerstyle. Bunları elle manuel stil tanımlaması yapabildiğimiz gibi style classı da atayabiliyoruz. Eğer elle stil yazarsak gridimizi oluşturan html çıktısında fazlasıyla kod tekrarı olur, bu ve yönetilebilirlikten dolayı class atamak en performanslı çözüm olacaktır.

    <asp:GridView runat="server" ID="GridView1">
        <HeaderStyle/>
        <RowStyle/>
        <AlternatingRowStyle/>
        <FooterStyle/>
        <PagerStyle/>
    </asp:GridView>

Şeklinde gridimizi oluşturuyoruz, sonrasında herbir kalıp için css mizi yazıyoruz.

    <style type="text/css">
        body{font-size:12px;font-family:Arial}
        /* GridView */
        .grid caption, tbody, tfoot, thead, tr, th, td,form {
	        margin: 0;
	        padding: 2px;
	        border: 0;
	        outline: 0;
	        color:#333;
	        font-size:12px;
        }
        .grid a:hover{color:#008aeb}
        .grid{border:none;width:100%;}
        .grid .header{background-color:#e5e5e5;height:30px;cursor:pointer;text-align:left}
        .grid .pager table{background-color:#333333;margin:5px auto}
        .grid .pager table td{font-size:15px;background-color:#3e3e3e}
        .grid .pager table td span{display:block;width:25px;height:20px;text-align:center;color:#868686;background-color:#333333}
        .grid .pager table td a{display:block;width:25px;height:20px;text-align:center;color:White}
        .grid .pager table td a:hover{background-color:#333333}
        .grid .row{}
        .grid .alternate{background-color:#f6f6f6;}
        .grid .alternate:hover,.grid .row:hover{background-color:#a8a8a8;cursor:pointer;}
        .grid .footer{background-color:#e3f1f8;font-weight:bold;}
    </style>

Son olarak gridimize class ları veriyoruz ve sitil olayını sonlandırıyoruz.

    <asp:GridView runat="server" ID="GridView1" CssClass="grid">
        <HeaderStyle CssClass="header" />
        <RowStyle CssClass="row" />
        <AlternatingRowStyle CssClass="alternate" />
        <FooterStyle CssClass="footer" />
        <PagerStyle CssClass="pager" />
    </asp:GridView>

Gördüğünüz gibi çok kolay bir şekilde gridimizi şekillendirdik. Hız kesmeden birde sayfalama işleminin nasıl yapıldığına bir bakalım. Bunun için ilk önce gridimizin sayfalama özelliğini AllowPaging=”true” diyerek aktif ediyoruz. Sonrasında olaylar (events) kısmından onpageindexchanging olayına çift tıklıyor ve ilgili olayı gerçekleştirecek methodu oluşturuyoruz. Kodumuz şu şekilde..

    protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GridView1.PageIndex = e.NewPageIndex; // yeni sayfa indexini gridimizin PageIndex değerine setliyoruz.
        GridViewDoldur(); //gridimizi tekrar dolduruyoruz.
    }
    

Kodlarımızın tamamı şu şekilde.

        <asp:GridView runat="server" ID="GridView1" CssClass="grid" AllowPaging="true" onpageindexchanging="GridView1_PageIndexChanging">
            <HeaderStyle CssClass="header" />
            <RowStyle CssClass="row" />
            <AlternatingRowStyle CssClass="alternate" />
            <FooterStyle CssClass="footer" />
            <PagerStyle CssClass="pager" />
        </asp:GridView>
    
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            GridViewDoldur();
        }
    }

    protected void GridViewDoldur() {
        GridView1.DataSource = db.DTGetir("Select top 100 * from EKOTEKNOBAYILOG order by id desc");
        GridView1.DataBind();
    }

    protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GridView1.PageIndex = e.NewPageIndex;
        GridViewDoldur();
    }
    

2 satırda sayfalama işlemimizide yapmış olduk. Bu şekilde ki bir sayfalama işlemi küçük projelerde rahatlıkla kullanılabilir fakat kayıt sayısı arttıkça performansda düşer. Neden düşer ? Çünkü ilk anda veri kaynağındaki tüm veriyi önce gridimize yüklüyoruz ve sayfalamayı grid içerisinde yapıyoruz. Bu durumun tersi olması durumunda performans artacaktır. Şimdide footer yani gridin en alt kısmının kullanıma bir bakalım. Neden footer kullanmamız lazım onuda hemen söyleyeyim. İlk sebep, hizalama problemlerinin çıkmaması ve haliyle çok daha derli toplu bir görüntü elde etmemiz. İkinci ve bence en önemlisi sebep ise gridview içerisindeki veriyi word, excel yada farklı bir formatta dışarı aktarmak istediğimizde hiç bir tasarımsal sıkıntının doğmaması. Footerı göstermek için ilk önce ShowFooter=”true” yapıyoruz. Artık footerimizi kullanabiliriz. Mantığını anlamak adına bir örnek yapalım.

    protected void GridViewDoldur() {
        GridView1.DataSource = db.DTGetir("Select top 10 * from EKOTEKNOBAYILOG order by id desc");
        GridView1.DataBind();

        decimal toplamSayi = 0; //burada basit bir toplama işlemi yapıyoruz. 6. sutundaki verileri alt alta topluyoruz.
        for (int i = 0; i < GridView1.Rows.Count; i++)
        {
            toplamSayi += Convert.ToDecimal(GridView1.Rows[i].Cells[6].Text);
        }

        GridView1.FooterRow.Cells[3].Text = "Toplam: " + GridView1.Rows.Count + " kayıt."; // kaçtane kayıt olduğunu footerımızın 3. sutununa yazıyoruz.
        GridView1.FooterRow.Cells[6].Text = toplamSayi.ToString(); // topladığımız değerleri footerdaki 6. sutuna yazıyoruz.
    }
    

Görüldüğü üzere footer kullanımıda oldukça basit. Herşey gayet derli toplu ve kontrolümüz altında. Şuana kadar ki örneklerimizi gridviewımızı otomatik doldurarak yaptık, şimdide veri kaynağından gelen veriyi nasıl özelleştirebiliriz buna bir bakalım. İlk önce sutunlarımızı kişiselleştirip istediğimiz sutunları alalım. Bu işlem için önce AutoGenerateColumns=”false” yapmamız gerekiyor, bunun nedenide bu işlemi biz manuel olarak elle yapacak olmamız. Örnekte kendi verikaynağımdaki isimleri kullanacağım

        <asp:GridView runat="server" ID="GridView1" CssClass="grid" ShowFooter="true" AutoGenerateColumns="false">
            <HeaderStyle CssClass="header" />
            <RowStyle CssClass="row" />
            <AlternatingRowStyle CssClass="alternate" />
            <FooterStyle CssClass="footer" />
            <PagerStyle CssClass="pager" />

            <Columns>
                <asp:BoundField DataField="id" HeaderText="Id" />
                <asp:BoundField DataField="tarih" HeaderText="Tarih" />
                <asp:BoundField DataField="sessionid" HeaderText="Oturum Kimliği" />
            </Columns>

        </asp:GridView>
    

Gördüğünüz üzere Columns adında bir bölüm oluşturup altına istediğimiz sutunları tanımladık. Şimdi verimizi biçimlendirelim (format). Ne demek bu ? Tarih, sayı vb.. verileri kendi ihtiyacımız doğrultusunda düzenleyebilmemize olanak sağlayan yapılardır. Örneğin; veritabanından gün/ay/yıl şeklinde gelen bir tarihi ay.gün.yıl şekline çevirmek gibi.. Burada şöyle bir püf noktası bulunuyor, verikaynağında ki veri tipinin tarih yada sayı olması gerekiyor. Yani veri kaynağında string şeklindeki bir tarihe yada sayıya direk biçimlendirme yapamıyoruz. Kendi oluşturduğumuz sutunlarda DataFormatString özelliğini kullanarak çok kolay bir şekilde istediğimiz biçimlendirmeyi rahatlıkla yapabiliyoruz. DataFormatString=” 0:n}”, DataFormatString=”{0:MM.dd.yyyy}” gibi.. Biçimlendirme işlemleri ve parametleri hakkında burayı ziyaret edebilirsiniz.

Herşey iyi güzel ama verikaynağında olmayan bir alanı gridimize nasıl ekleyeceğiz diye sorabilirsiniz. Bu noktada imdadımıza TemplateField koşuyor. Hemen örneğimize bakalım.

</span>
<pre>
        <asp:GridView runat="server" ID="GridView1" CssClass="grid" AutoGenerateColumns="false">
            <HeaderStyle CssClass="header" />
            <RowStyle CssClass="row" />
            <AlternatingRowStyle CssClass="alternate" />
            <FooterStyle CssClass="footer" />
            <PagerStyle CssClass="pager" />
            <Columns>
                <asp:BoundField DataField="id" HeaderText="Id" />
                <asp:BoundField DataField="tarih" HeaderText="Tarih" />
                <asp:BoundField DataField="sessionid" HeaderText="Oturum Kimliği" DataFormatString="{0:n}" />
                <asp:TemplateField HeaderText="Bu bir textbox">
                    <ItemTemplate>
                        <asp:TextBox runat="server" ID="TextBox1" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Bu bir literal">
                    <ItemTemplate>
                        <asp:Literal runat="server" ID="Literal1" Text='<%#Eval("id") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField>
                    <ItemTemplate>
                        <a href="">Detay</a>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

Yukarıda da gördüğünüz gibi TemplateField içine ItemTemplate ile istediğimiz kontrolü yada herhangi birşeyi rahatlıkla girdik. Burada dikkat ederseniz Eval(“id”) şeklinde bir kullanım gerçekleştirdik. Eval veri kaynağımızdan manuel bir şekilde veriyi gridimizin içine çekmemize olanak sağlayan bir fonksiyon. Şöyle bir soru gelebilir buraya textbox ları ekledik fakat içerisindeki veriyi nasıl alabiliriz ? Bu sorunun cevabını bir sonraki yazımda yazacağım.

Gridview in çok fazla özelliği bulunuyor. Bu özelliklere verileri güncelleme ve silme gibi olaylarda dahil fakat ben bu özelliğin kullanılmasını çok sağlıklı bulmuyorum. Neden bulmuyorum, çünkü sayfa yeniden yükleniyor, haliyle griddeki verilerde yeniden yükleniyor, bu son son derece gereksiz ve verimsiz. Bu düzenleme işlemi için hem grid tarafında hemde kod tarafına bir sürü kod yazmamızın gerekmeside ayrı bir handikap. Düzenleme işlemi için jQuery ile veriyi olduğu yerde düzenleme (inline edit) yöntemini hem daha kolay kullanılabilir hemde maliyetinin daha az olduğunu düşünüyorum. Bu konuyu ilerleyen günlerde ele alacağım. Dipnot olarak burada dursun istedim.

Footer ile ilgili aklıma bir şey daha geldi. Gridimize footer ekledik fakat patronumuz yada iş verenimiz bize footerin aynısının headerında üstünde olmasını istedi. Böyle bir istek neden gelir ? Gridimizde çok fazla satır olduğunu düşünürsek, alt toplamlar yada diğer bilgilere erişmek için kullanıcı sayfayı dibe kadar çekmek zorunda kalacaktır. Bu işi yapmanın bir çok yolu bulunuyor. Tabiri caizse bir gumul kodun yazılacağı çok can sıkıcı bir durumdur bu. Bu noktada imdadımıza jQuery yetişiyor. Hemde ne yetişme, bir satırda olayı çözüyoruz. Footerımıza bir class atamıştık, ilk önce footerımızı seçiyoruz sonrasında klonluyoruz (clone) ve headerımızın önüne ekliyoruz. Bu sayede footerda değişiklikler olduğunda aynen headerada uygulanmış oluyor. Sürekli footera ayrı kod headerdakine ayrı kod yazmaktan kurtulmuş oluyoruz.

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            $(".grid .header").before("<tr class='footer'>" + $(".grid .footer").clone().html() + "</tr>");
        })
    </script>
    

Gridview ile ilgili yazacaklarım şimdilik bu kadar, umarım anlaşılır bir yazı olmuştur. Yukarıda da belirttiğim gibi gridview ile ilgili yazacak çok fazla şey bulunuyor. Ben en ana hatlarıyla ve en sık kullanılan özelliklerini anlatmaya çalıştım. İlerleyen günlerde daha farklı özelliklerini ele almaya çalışacağım, herkese kolay gelsin.

  • Pingback: GridView içindeki kontrole erişme (Findcontrol) | asp.net, jquery ve diğer web teknolojileri üzerine()

  • http://- Mehmet Emin Taş

    Mesela Gridviewe ürünler tablosundaki verilerimi döküyorum, tabloda ürünün kategorisinin alanı var ve rakamla yazılı. Yapmak istediğim olay kategorinin idini değilde ide eşit olan kategorinin ismini kategoriler tablosundan çekip göstermek istiyorum bunu nasıl yapabilirim. Teşekkürler

    • apoStyLEE

      Merhaba, istediğinizi yapmak için basit bir sql cümlesi yazmalısınız. Örneğin; Select urun.*,kategori.adi from urun, kategori where kategori.id = urun.kategoriId gibi..

  • Hüseyin

    Proje linkini verebilir misiniz?

  • Oğuzhan

    Selam, grid içerisinde tarih sütununu son ödeme tarihi gibi düşünürsek. 5 günü yada daha az günü kalan kayıtları farklı renkte göstermesini istiyorum. Bu renk olayını sanırım jquey ile olacak, ve yine günde bir defa çalışması için timer gerekecek. Bu kısımlara gelmeden önce asıl noktayı yani tarih bilgisi yaklaşan kayıtları seçmeyi yapamadım. fikir verebilirseniz sevinirim.