2009-03-11 19 views
3

GridView ile çok fazla çalışmadım ve bununla uğraştıktan sonra, ihtiyacım olandan daha karmaşık, ancak bunu beklediğim bazı temel yetenekleri eksik buluyorum. Kuşkusuz bu uygulama, özellikle de bunu bildirimde bulunduğunda, veri kümesine bağlı kalma zamanının% 90'ı dikkate alındığında anlamlıdır, ancak ben bunu bir IEnumerable<T> koduna bağlamayı düşünmekteyim. Ben gerekenlerKendi GridView uygulamamı yazmalı mıyım?

kolayca aşağıdakileri yapmak için yeteneğidir

  • a) sütunlar türden yalnızca belirli özelliklere sınırlandırılabilir bir IEnumerable<T> bağlanabilir T
  • b) dönmek için sorgulanabilir
  • her satır bir hücre olabilir onun satırların bir koleksiyon hücre güzel olurdu aşağıdaki arabirim uygulama

için temelde bir şey bağlıydı, bu özelliğe göre aranır

public interface IEasyGridBinder { 
    void Bind<T>(IEnumerable<T> bindableObjects, params string[] propertiesToBind); 
    IList<IDictionary<string, string>> Values {get;} 
} 
Yani bu olsun, ben GridView devralır ve bu arayüzü uygulayan ya da ben sadece yabancıyım bunları yapmak için gerçekten çok basit bir yolu vardır kendi özel EasyGridBinder yazmalıyım?

P.S.

Takip eden soru Bonus puan Ben

myGrid.Bind(myEntities, e=>{e.Id; e.Name; e.Customer.Name;}); 

gibi bir şey yazabilirsiniz Ama eğer ben ifadeler

üzerinde okuduktan sonra kendimi anlamaya varsayalım:
orijinal verileri almak için bir yolu var mı bu ızgara görünümüne girdi ve html'ye dönüştürülmedi mi? Bir giriş boş bir dize olarak alınan alan varsa, hücre " " içeriyor gibi görünüyor, yani boş bir dize ve boşluk girdisi arasında ayrım yapmak için bir yolu yok mu? Bu gerçekten de durum buysa, muhtemelen GridView'ın işlevselliğinin çoğunu yeniden uygulayacağım.

+0

Aslında hiç kimse bu sorun için iyi bir çözümün bulunmadığı konusunda çok şaşırıyorum. Sanırım bu gece önümde bir işim var, bu birkaç gündür demomu engellemeye başladı. Muhtemelen bu kodu google kodunda yayınlayacağım –

cevap

0

Gerekli davranışı eklemek için uzantı yöntemlerini kullanmanızı öneririm. Bunun tek dezavantajı, "Değerleri" bir özellik olarak ekleyememenizdir.

+0

Evet, ancak bunları yapmak için gerçekten basit bir yol varsa, sadece bir uzantı yazmak istiyorum. Eğer üç satırdan fazla değilse, alt sınıfta da olabilirim çünkü muhtemelen başka şeyler yapmak zorunda kalacağım. –

+0

Kesinlikle 3 satırdan daha fazla olacaktır. Ancak, uzantı yöntemini kullanmanın yararı, "GridView" yerine "EasyGridBinder" ile değiştirmek için mevcut herhangi bir ASPX işaretlemesini değiştirmek zorunda kalmamanızdır. – David

+0

Evet, başladığım şey buydu, ancak uzantı yöntemlerinin, kolaylık kısayollarından başka bir şey olmaması gerektiğine dair bir kuralım var, herhangi bir gerçek davranış, kodlar olma eğilimindedir. –

1

GridViews AutoGenerateColumns özelliğini false olarak ayarlarsanız, yalnızca belirttiğiniz sütunları oluşturur. Bunu, BoundFields'ı oluşturarak ve bunları Gridview Sütunları koleksiyonuna ekleyerek yaparsınız.

GridView gv = new GridView(); 
gv.AutoGenerateColumns = false; 

BoundField bf = new BoundField(); 
bf.DataField = "Id"; 
bf.HeaderText = "ID"; 
gv.Columns.Add(bf); 

BoundField bf = new BoundField(); 
bf.DataField = "Name"; 
bf.HeaderText = "Name"; 
gv.Columns.Add(bf); 

BoundField bf = new BoundField(); 
bf.DataField = "Customer.Name"; 
bf.HeaderText = "Customer Name"; 
gv.Columns.Add(bf); 

gv.DataSource = IEnumerable<T>; 
gv.DataBind(); 

Ben yorumlarda bu açıklamayı yazılı ama daha görünür olduğu yere dışarı taşımak ve bir kod örneği eklemek düşündüm vardı:

Yukarıdaki dinamik bir GridViewDisplayAttribute sınıf oluşturmak yapmak için hangi Öznitelikten devralır. GridViewDisplayAttribute bir HeaderText özelliği verin. HeaderText belirterek T'nin özelliklerini dekore edin. HeaderText kullanarak her bir dekore edilmiş özellik için BoundFields yaratma T özelliklerinin yinelenen.

Hızlı denenmemiş kod örneği:

using System; 
public class GridViewDisplayAttribute : Attribute 
{ 
public GridViewDisplayAttribute(string headerText) 
{ 
     HeaderText = headerText; 
} 
    public readonly bool HeaderText; 
} 

GridView gv = new GridView(); 
gv.AutoGenerateColumns = false; 

Type t = <T>.GetType(); 
PropertyInfo[] pis = t.GetProperties(); 

foreach (PropertyInfo pi in pis) 
{ 
    GridViewDisplayAttribute[] gvdaArray = pi.GetCustomAttributes(
     typeof(GridViewDisplayAttribute), true); 

    foreach (GridViewDisplayAttribute gvda in gvdaArray) 
    { 
     BoundField bf = new BoundField(); 
     bf.DataField = pi.Name; 
     bf.HeaderText = gvda.HeaderText; 
    } 

    gv.Columns.Add(bf); 
} 

gv.DataSource = IEnumerable<T>; 
gv.DataBind(); 
+0

Hmm, bu oldukça yararlı olacak, DataKeyNames ile çok şansım olmadı. Teşekkürler! –

+0

Dinamik hale getirmek için bir GridViewDisplayAttribute: Attribute sınıfı oluşturun. GridViewDisplayAttribute öğesinin bir HeaderText özelliği verilmesi, HeaderText öğesinin belirtildiği T özelliklerini belirtmenize izin verir. HeaderText kullanarak her bir dekore edilmiş özellik için BoundFields yaratma T özelliklerinin yinelenen. – ahsteele

2

LinqDataSource veri kaynağı için destek mağaza olarak nesneyi belirlemenizi sağlar.Daha sonra GridView'ı bu veri kaynağına bağlarsınız. .aspx'te biraz daha fazla bildirim var, ancak özellik bloğu GridView'ı yeniden oluşturmaya daha yakın ve yaklaştıkça, daha sonra devam etmek için daha az kod.

+0

Fena değil ama her yerde dizeler! Refactoring desteği var. –

+0

Demek istediğim sadece bu mu, yoksa GridView'dan çıkmak için standart olması gereken şeyleri tartıştığım bu operasyonlar mı? En az şaşkınlık ilkesi - başarısızlık –

+0

Benim deneyimlerime göre, MS'nin bu tür problemlere saldırma şekli neredeyse hiçbir şeyi yapmanın en az şaşırtıcı yolu değildir, ama sonunda (1) zaten orada olanlarla en iyi şekilde çalışır. (2) İstediğimi düşündüğümden çok istediğim şey olmaktan çıkıyor. –