Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Ömer Faruk ZORLU
Ömer Faruk ZORLU
http://b.zor.lu
İletişme geçmek için tıklayın.
5 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: ColumnGenerator DD GenerateFields IAutoFieldGenerator MetaTable pagetemplate pagetemplatetype PageTemplateType RowGenerator scaffolding ASP.NET Ömer Faruk ZORLU
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : ASP.NET
Yayınlanma Tarihi : 14.3.2010
Okunma Sayısı : 33344
Yorum Sayısı : 0     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 21.11.2024
Turhal Temizer
Mac OS/X Removing CUDA 21.11.2024
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 21.11.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 21.11.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
ASP.NET Dynamic Data - Gelişmiş Scaffolding
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon

Merhabalar, daha önce ASP.NET Dynamic Data(yazının devamında DD kısaltmasını kullanacağım) hakkında bazı bilgileri yayınlamıştım. Yeni bir makale konusunda düşünürken makale konusu olarak gerçek bir DD projesinde kullanıcı tarafından gelebilecek isteklerin hızlı bir şekilde nasıl karşılanabilineceğinden bahsetmenin uygun olduğuna karar verdim.
Yazılımcı gözüyle değerlendirmek gerekirse kullanıcı gereksinimleri konusunda gözden kaçan bir çok gereksinimi görülmeyebilir.  Örneğin bir tablo içindeki kayıtların listelenmesi yazılımcı için gayet yeterlidir ancak kullanıcı gözüyle bakıldığında her şeyin listelenmesi çoğu zaman gereksiz olacaktır. Bu kapsamda kullanıcı isteklerine karşılık sorun çözümüyle alakalı makalele dizisinin ilkini yazmaya başlıyorum. Daha önceki makalelerde bahsettiğim isimlendirme, biçimlendirme vb. gibi temel işlemlere bu makalede değinmeyeceğim.

Kullanıcı tarafında tablo üzerindeki her alanın(column) görüntülenmesi istenmeyebilir. Bazı durumlarda ise tüm kayıtların listelenmesi kullanım kolaylığı açısından sıkıntılı olabilir.

Scaffolding tekniğiyle istenilen alanların tüm şablonlarda görüntülenmesini engelleyebiliyoruz. Özellikle listeleme sayfalarında tüm alanların sayfada görünür halde olması yatay olarak uzayan bir sayfaya neden olur ancak bu alanları klasik scaffolding tekniği ile gizlersek diğer şablonlardanda kayboluverir.  İşte burada asıl sorun ortaya çıkıyor: Gizlenen alanların kullanıcı tarafından düzenlenmesi gerekiyorsa yada detaylı görüntüleme şablonunda tüm alanların görüntülenmesi gerekiyorsa ne yapacağız?

Aletleri geliştirmek DD için her zaman kazanımdır. Bu senaryoda scaffolding tekniğini sayfa şablonlarına göre nasıl özelleştirebileceğimizi öğreneceğiz.

Kullanabileceğimiz veri bileşenleri(GridView, FormView, DetailsView vb.) veri listeleme sırasında listeleme işlemi için IAutoFieldGenerator arayüzünü uygulayan bir sınıf ile veri alanları üzerindeki kararını verir. Varsayılan alan oluşturucularda verideki tüm alanlar DD bildirimleri uygunlandıktan sonra(scaffolding gibi kısıtlamalar vb.) listelenir. Yapılması gereken şey ise veri listeleme işini gerçekleştirme görevini yazacağımız bir sınıfın üstlenmesidir.

IAutoFieldGenerator arayüzünü uygulayan sınıfımız:

 

namespace Eposta.Core.CustomFieldGenerator
{
    using System.Collections.Generic;
    using System.Web.UI;
    using System.Web.DynamicData;

    /// <summary>
    /// Bu sınıf veri listelemesini işlemlerini
    /// özelleştirmek amacıyla yazılmıştır.
    /// </summary>
    public class CustomColumnGenerator : IAutoFieldGenerator
    {
        /// <summary>
        /// Veri listelemesi için incelenecek
        /// tablo değişkenini tutar
        /// </summary>
        protected MetaTable mTable = null;

        #region IAutoFieldGenerator Members
        /// <summary>
        /// Listeleme işlemini gerçekleştirecek method
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public System.Collections.ICollection GenerateFields(Control control)
        {
            // Uygun kolonların biriktirildiği koleksiyon
            List<DynamicField> dynFieldList = new List<DynamicField>();

            // MetaTable atanmışsa
            if (mTable != null)
            {
                // Her bir MetaColumn için
                foreach (MetaColumn mColumn in this.mTable.Columns)
                {
                    // Scaffolding ataması yapılmışsa koleksiyona eklenmesi
                    // uygun değildir. Eğer bu kontrol yapılmazsa ilgili
                    // alan görüntülenecektir. Çünkü tüm sorumluluğu almış
                    // bulunuyoruz
                    if (
                            !mColumn.Scaffold
                        )
                        continue;

                     DynamicField dynField = new DynamicField();
                    dynField.DataField = mColumn.Name;

                    dynFieldList.Add(dynField);
                }
            }

            return dynFieldList;
        }

        #endregion
    }
}

 

Scaffolding tekniğini denetleyerek görüntüleme işlemini üstlenen sınıfımız artık hazır. Şimdi sıra şablonlara göre bu denetleme işlemine geldi. Varsayılan şablonlar için bir enum tanımlayıp GenerateFields methodunda şablona görede bir denetleme yapmamız gerecektir.

 

namespace Eposta.Core.Enums
{
    public enum PageTemplateType
    {
        Details,
        Edit,
        Insert,
        List,
        ListDetails
    }
}

 

Özelleştirme işlemlerinin uygulanabilmesi için özel bir öznitelik geliştirip bildirimlerin bu öznitelik üzerinden gerçekleştirmesi gerekiyor bunun için aşağıdaki sınıfı kullanabiliriz.

 

using System;
using Eposta.Core.Enums;

namespace Eposta.Core.CustomAttributes
{
    [AttributeUsage(AttributeTargets.Property)]
    public class CustomHiddenColumnAttribute : Attribute
    {
        /// <summary>
        /// İlgili alanın gizlenmesi gereken sayfa şablonları belirleniyor
        /// </summary>
        public PageTemplateType[] PageTemplateTypes { get; private set; }

        /// <summary>
        /// Parametresiz bir constructor yazılması mecburi ancak
        /// kullanılmaması için hata fırlatılması daha uygun
        /// </summary>
        public CustomHiddenColumnAttribute()
        {
            throw new InvalidOperationException();
        }

        /// <summary>
        /// Sayfa şablonlarının atama işleminin kolaylaştırılması
        /// nedeniyle params yöntemi kullanılmıştır. Öznitelik
        /// tanımlamasında AllowMultiple=true atamasıda yapılabilir
        /// </summary>
        /// <param name="PageTemplateParams"></param>
        public CustomHiddenColumnAttribute(params PageTemplateType[] PageTemplateParams)
        {
            this.PageTemplateTypes = PageTemplateParams;
        }
    }
}

 

Bu özniteliğin örnek tanımlaması aşağıdaki gibidir. Daha öncede belirttiğim gibi öznitelik yazmayı çok severim :) Bundan böyle sadece aşağıdaki kodu kullarak tüm kodu yazmadan işimizi halledebiliriz.

 

[CustomHiddenColumn(
        PageTemplateType.List, PageTemplateType.ListDetails
)]

public string SmtpHost { get; set; }


Madem bu kadar kod yazdık birde MetaColumn nesneleri için genişletilmiş bir method yazarak kolonda ve şablona göre gizlilik bildirimi yapılmışmı diye kontrol edelimki her seferinde bir yığın kod yazmaktan kurtulalım.

using System.Linq;
using Eposta.Core.CustomAttributes.UIHint;
using Eposta.Core.CustomAttributes;
using Eposta.Core.Enums;
/// <summary>
/// Ömer Faruk ZORLU
/// </summary>
namespace Eposta.Core.Extentions
{
    public static class MetaColumnExtentions
    {
        /// <summary>
        /// Sayfa şablonuna göre alanın gizlilik durumunu dönderir
        /// </summary>
        /// <param name="mColumn"></param>
        /// <param name="pTemplateType"></param>
        /// <returns></returns>
        public static bool IsHidden(this System.Web.DynamicData.MetaColumn mColumn, PageTemplateType pTemplateType)
        {
            // Kolon üzerinde atanmış ustomHiddenColumn özniteliği alınıyor
            // Eğer çoklu tanımlama(AllowMultiple) ya izin verilmişse bir
            // döngü içerisinde kontrol edilmesi gerekir
            CustomHiddenColumnAttribute chCAttr =
                mColumn.Attributes.OfType<CustomHiddenColumnAttribute>().FirstOrDefault();

 

             //  Herhangi bir öznitelik ataması yoksa gizli değildir
            if (chCAttr == null)
                return false;

             // İlgili alan için yapılan gizlilik bildirimleri parametrede
            // gönderilmiş sayfa şablonunu içeriyorsa gizlidir
            return chCAttr.PageTemplateTypes.Contains(pTemplateType);;
        }
    }
}

Artık daha önce yazdığımız alan oluşturucu sınıf üzerinde özel gizleme yapımızı denetleyen kodlar yazabiliriz. Yukarıda yazdığımız sınıfa yeni eklenen kodlar kalın olarak yazılmıştır.

using System.Collections.Generic;
using System.Web.DynamicData;
using System.Web.UI;
using Eposta.Core.Extentions;
using Eposta.Core.Enums;

 

namespace Eposta.Core.CustomFieldGenerator
{
    /// <summary>
    /// Bu sınıf veri listelemesini işlemlerini
    /// özelleştirmek amacıyla yazılmıştır.
    /// </summary>
    public class CustomFieldGenerator : IAutoFieldGenerator
    {
        /// <summary>
        /// Veri listelemesi için incelenecek
        /// tablo değişkenini tutar
        /// </summary>
        protected MetaTable mTable = null;

        protected PageTemplateType pTemplateType;

         #region ctor

         public CustomFieldGenerator(MetaTable _mTable, PageTemplateType _pTemplateType)
        {
            this.mTable = _mTable;
            this.pTemplateType = _pTemplateType;
        }
        #endregion

         #region IAutoFieldGenerator Members
        /// <summary>
        /// Listeleme işlemini gerçekleştirecek method
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public System.Collections.ICollection GenerateFields(Control control)
        {
            // Uygun kolonların biriktirildiği koleksiyon
            List<DynamicField> dynFieldList = new List<DynamicField>();

            // MetaTable atanmışsa
            if (mTable != null)
            {
                // Her bir MetaColumn için
                foreach (MetaColumn mColumn in this.mTable.Columns)
                {
                    // Scaffolding ataması yapılmışsa koleksiyona eklenmesi
                    // uygun değildir. Eğer bu kontrol yapılmazsa ilgili
                    // alan görüntülenecektir. Çünkü tüm sorumluluğu almış
                    // bulunuyoruz
                    if (
                            !mColumn.Scaffold
                        )
                        continue;

                     // List ve ListDetails şablonları için IsHidden
                    // genişletilmiş methodu ve IsLongString methodunu
                    // kontrol ediyoruz ancak Details şablonu için
                    // IsLongString methodunu kontrol edip gizlersek
                    // uzun metin alanlar görüntülenmeyecek yani ufak bir
                    // bug oluşacaktır.
                    switch (this.pTemplateType)
                    {
                        case PageTemplateType.Details:
                            if (mColumn.IsHidden(this.pTemplateType))
                                continue; // foreach
                            break;
                        case PageTemplateType.List:
                            if (mColumn.IsHidden(this.pTemplateType) ||
                                    mColumn.IsLongString)
                                continue; // foreach
                            break;
                        case PageTemplateType.ListDetails:
                            if (mColumn.IsHidden(this.pTemplateType) ||
                                    mColumn.IsLongString)
                                continue; // foreach
                            break;
                        default:
                            break;
                    }

                     // Varsayılan şablonların haricinde uzun metinlerin
                    // görüntülenmesini engellemek amacıyla bu kontrol
                    // yapılıyor
                    if (mColumn.IsLongString)
                        continue;

                     DynamicField dynField = new DynamicField();
                    dynField.DataField = mColumn.Name;

                     dynFieldList.Add(dynField);
                }
            }

            return dynFieldList;
        }

        #endregion
    }
}

Son adımında ise ilgili veri kontrolüne veri listeleme işlemini bizim üstleneceğimizi bildirmek gerekiyor. GridView nesnesi için ColumnGenerator DetailsView içinse RowGenerator parametresi kullanılıyor. Son haliyle List.aspx.cs ve Details.aspx.cs şablon kodları aşağıdaki gibi tanımlanmalıdır.


List.aspx.cs kodları:

using System;
using System.Web.DynamicData;
using Eposta.Core.CustomFieldGenerator;
using Eposta.Core.Extentions;

public partial class List : System.Web.UI.Page
{
    protected MetaTable table;

    protected void Page_Init(object sender, EventArgs e)
    {
        DynamicDataManager1.RegisterControl(GridView1, true /*setSelectionFromUrl*/);
        table = GridDataSource.GetTable();
        GridView1.ColumnsGenerator = new CustomFieldGenerator(table, Eposta.Core.Enums.PageTemplateType.List);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        Title = table.DisplayName;
        InsertHyperLink.NavigateUrl = table.GetActionPath(PageAction.Insert);

         // Disable various options if the table is readonly
        if (table.IsReadOnly)
        {
            GridView1.Columns[0].Visible = false;
            InsertHyperLink.Visible = false;
        }
    }

    protected void OnFilterSelectedIndexChanged(object sender, EventArgs e)
    {
        GridView1.PageIndex = 0;
    }
}


Details.aspx.cs kodları:

using System;
using System.Linq;
using System.Web.DynamicData;
using System.Web.UI.WebControls;
using Eposta.Core.CustomFieldGenerator;
using Eposta.Core.CustomAttributes;

public partial class Details : System.Web.UI.Page {
    protected MetaTable table;

    protected void Page_Init(object sender, EventArgs e) {
        DynamicDataManager1.RegisterControl(DetailsView1);
    }

    protected void Page_Load(object sender, EventArgs e) {
        table = DetailsDataSource.GetTable();
        DetailsView1.RowsGenerator = new CustomFieldGenerator(table, Eposta.Core.Enums.PageTemplateType.Details);
       
        Title = table.DisplayName;
       
        ListHyperLink.NavigateUrl = table.ListActionPath;
    }

    protected void DetailsView1_ItemDeleted(object sender, DetailsViewDeletedEventArgs e) {
        if (e.Exception == null || e.ExceptionHandled) {
            Response.Redirect(table.ListActionPath);
        }
    }
}

Çözüm itibari ile Grup tablosunda yapılan tanımlalarla listeleme sayfa şablonlarında bazı alanların gizlenmesini güncelleme ve detaylı görüntüleme sayfa şablonlarında ise kullanıcının verileri görüntülemesine ve düzenlemesine imkan tanımış olduk. Ekran görüntüleri aşağıdaki gibidir.

 

Güncelleme ekranı:


Listeleme ekranı:


Bir yazının daha sonuna geldik. Kullanıcı gereksinimleriyle alakalı makaleler devam edecektir. Bir sonraki makalede görüşmek üzere. Yaşasın dinamizm!
 

Ömer Faruk ZORLU

Makale:
ASP.NET Dynamic Data - Gelişmiş Scaffolding ASP.NET Ömer Faruk ZORLU
  • Yazılan Yorumlar
  • Yorum Yaz
Bu konu hakkında yayınlanan yorum bulunmamaktadır.
"Yorum Yaz" tabını kullanarak sizde yorumlarınızı yazabilirsiniz.
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor