2009-06-03 27 views
8

GridView'ı bir çok yerde aynı nesneye bağlı olarak kullanan oldukça büyük bir asp.net web sitesine sahibim. Her satırı özelleştirmek için bir öğe şablonu kullanıyorum. Ancak tüm sayfalarda aynı şablona sahip olmak için & kopyalamak zorundayım, öğe şablonunu her sayfaya yapıştırın. Açıkçası bu en iyi çözüm değil. Bunun üzerine, bazı yapılandırma dosyalarını değiştirerek GridView tarafından kullanılan şablonu değiştirebiliyorum. Bir seçenek DataGrid ile bir kullanıcı denetimi oluşturmak ve her sayfada kullanılmak üzere gerekli özellikleri ortaya çıkarmak olacaktır. Ancak bu, şablonu dinamik olarak değiştirebilmenin ikinci şartını yerine getirmez. Temel olarak GridView'a bir şablon kullanmanın ve bunu dinamik olarak yapabilmenin bir yolunu arıyorum. Herhangi bir fikir yardımcı olabilir.GridView öğe şablonunu dinamik olarak değiştirin

1.) kodu dinamik olarak her TemplateField kurmak ve bazı yapılandırma dayanarak bu geçiş: gördüğüm kadarıyla istediğini gerçekleştirmek amacıyla

+0

Farklı tasarım şablonu şablonunu değiştirmek istiyor musunuz? –

+0

evet, farklı tasarım şablonlarına sahip olmak ve bunları dinamik olarak değiştirebilmek için – Albert

cevap

9

, iki seçeneğiniz vardır.
2.) Özel ızgaralarınız için kullanıcı denetimleri oluşturun ve bunları kullanın.

Bir UserControl kullanmak istemediğinizi söylediğinizi biliyorum çünkü bu, düzeninizi dinamik olarak değiştirme yeteneğinizi ortadan kaldıracaktır, ancak bu ön örneklemi bir örnekle sorgulamama izin verin.

Kullanıcı denetimlerini PlaceHolder Control kullanarak istediğiniz gibi dinamik olarak değiştirmek için yerleşik ASP.Net özelliklerini kullanabilirsiniz.

<asp:PlaceHolder ID="GridViewPlaceHolder" runat="server" /> 

Size özel ızgaralar şöyle çalışma zamanında dinamik olarak .ascx dosyalarındaki bildirimli inşa edilmiş ve daha sonra yerine yüklenebilir:

GridViewPlaceHolder.Controls.Add(LoadControl("~/Controls/MyCustomControl.ascx")); 

Şimdi, gerçekten o, hayatınızı kolaylaştıracak istiyorsanız Tüm özel ızgara denetimlerinizin devralacağı soyut bir temel sınıf oluşturabilir. Bu şekilde, kontrolleriniz yüklendiğinde genel olarak tedavi edilebilir.

public abstract class CustomGridControl: System.Web.UI.UserControl 
{ 
    public abstract Object DataSource { get; set; } 
} 

Basit ızgara işaretlemesindeki tanımlanabilir:

<asp:GridView ID="myGridView" runat="server" AutoGenerateColumns="false"> 
    <Columns> 
     <asp:TemplateField HeaderText="Name"> 
      <ItemTemplate> 
       <asp:Label Text='<%#Eval("Name") %>' runat="server"></asp:Label> 
      </ItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField HeaderText="Age"> 
      <ItemTemplate> 
       <asp:Label Text='<%#Eval("Age") %>' runat="server"></asp:Label> 
      </ItemTemplate> 
     </asp:TemplateField> 
    </Columns> 
</asp:GridView> 

Ve bu kontrol için geride kodunuzu şöyle görünecektir: kullanmaktadır

Şimdi
public partial class SimpleGrid : CustomGridControl 
{ 
    public override object DataSource 
    { 
     get { return myGridView.DataSource; } 
     set { myGridView.DataSource = value; } 
    } 
} 

sayfası veya denetim Bu sadece temel sınıfa vermeli ve bunu genel olarak kullanabilirsiniz. Aşağıdaki bunu nasıl kullanabileceğinize ilişkin basit bir örnek, ama açıkça noktası oluşturur düşünüyorum: orada Yani

protected void Page_Load(object sender, EventArgs e) 
{ 
    var dataSource = new List<MyCustomClass> 
         { 
          new MyCustomClass{Name = "Josh", Age = 43}, 
        new MyCustomClass{Name = "Bob", Age = 14}, 
        new MyCustomClass{Name = "Ashley", Age = 32}, 
         }; 

    DynamicallyLoadUserControlGrid("~/GridViewTemplates/SimpleGrid.ascx", dataSource); 
} 

private void DynamicallyLoadUserControlGrid(String controlLocation, List<MyCustomClass> dataSource) 
{ 
    var ctrl = (CustomGridControl)LoadControl(controlLocation); 
    ctrl.DataSource = dataSource; 
    ctrl.DataBind(); 

    GridViewPlaceHolder.Controls.Add(ctrl); 
} 

, onu var. Tüm bunları baştan çıkarmaya çalışan özel baştan çıkarıcı kodlar, hepsini manuel olarak kodda oluşturmaya çalışıyor. Ben tamamen manuel yolunu bunu başka bir cevapta yayınlayacağım, ama bir kez gördüğünüzde, bu yöntemin tercih edildiğini kabul edersiniz.

+0

Tankı çok çok iyi anladım, çok iyi çalıştığımı anladım :) –

5

Pekala, işte bu yüzden,% 100 elle işaretlenmiş alan örneklerini oluşturuyoruz.

Dinamik şablon sütunları oluşturmanın ilk adımı, System.Web.UI.ITemplate arabirimini uygulayan bir sınıf oluşturmaktır. Buradaki basit örneğimiz için bir etiket kullanacağım.DataBinding desteklemek amacıyla, el ne olursa olsun kontrol (ler) eklemeyi tercih üzerine olayı işlemek zorunda kalacağını

public class MyCustomTemplate : ITemplate 
{ 
    public String DataField { get; set; } 

    public MyCustomTemplate(String dataField) 
    { 
     DataField = dataField; 
    } 

    public void InstantiateIn(Control container) 
    { 
     var label = new Label(); 
     label.DataBinding += label_DataBinding; 

     container.Controls.Add(label); 
    } 

    void label_DataBinding(object sender, EventArgs e) 
    { 
     var label = (Label)sender; 
     var context = DataBinder.GetDataItem(label.NamingContainer); 
     label.Text = DataBinder.Eval(context, DataField).ToString(); 
    } 
} 

dikkat edin. Şablonunuzu geliştirdikten sonra, bunu kullanmak istediğiniz herhangi bir TemplateField için ItemTemplate olarak kullanabilirsiniz.

Kılavuzumuzu bağlamak istediğimiz bazı özel iş nesneleri koleksiyonumuz olduğunu varsayalım.

public class MyCustomClass 
{ 
    public String Name { get; set; } 
    public Int32 Age { get; set; } 
} 

manuel bir TemplateField olarak her sütunu oluşturmak ve sonra GridView koleksiyonumuzu bağlamak zorunda olacak.

protected void Page_Load(object sender, EventArgs e) 
{ 
    var dataSource = new List<MyCustomClass> 
         { 
          new MyCustomClass{Name = "Josh", Age = 43}, 
        new MyCustomClass{Name = "Bob", Age = 14}, 
        new MyCustomClass{Name = "Ashley", Age = 32}, 
         }; 

    DynamicGrid(dataSource); 
} 

private void DynamicGrid(List<MyCustomClass> dataSource) 
{ 
    var col = MyCustomTemplateCollection.GetTemplateCollection(); 

    foreach (DataControlField field in col) 
    { 
     myGridView.Columns.Add(field); 
    } 

    myGridView.DataSource = dataSource; 
    myGridView.DataBind(); 
} 
: Böyle bir şey olmazdı arkasında kodunuzda bu kullanma

public static class MyCustomTemplateCollection 
{ 
    public static DataControlFieldCollection GetTemplateCollection() 
    { 
     var col = new DataControlFieldCollection(); 

     var nameField = new TemplateField 
         { 
          HeaderText = "Name", 
          ItemTemplate = new MyCustomTemplate("Name") 
         }; 

     var ageField = new TemplateField 
         { 
          HeaderText = "Age", 
          ItemTemplate = new MyCustomTemplate("Age") 
         }; 

     col.Add(nameField); 
     col.Add(ageField); 

     return col; 
    } 
} 

: yapmak için bu daha temiz ve daha kolay hale getirmek için, bir statik yardımcı sınıfa TemplateField koleksiyonunun bina yukarı kapsüllü var

Sonuçta, bu, dinamik kullanıcı denetimleriyle aynı olan bir çıktı üretecektir, ancak görebileceğiniz gibi çok daha hantaldır. Bu ayrıca herhangi bir CSS özelliğini veya birden çok denetim türünü içermeyen çok basit bir örnektir. Bunu yapabilirsin, ama acı verici olur ve hep birlikte programlamayı bırakmak isteyebilirsin. Kullanıcı kontrol çözümüne gidin ve hayatınızı kolaylaştırın.

İlgili konular