2009-03-11 3 views
3

Я не слишком много работал с GridView, и после того, как ты его обманывал, считай, что он более сложный, чем мне нужно, но не хватает некоторых основных способностей, которые я ожидал бы от него. Несомненно, его реализация имеет смысл, учитывая 90-процентную цель привязки к набору данных, особенно когда это делается декларативно, но я намерен связать его с кодом IEnumerable<T>.Должен ли я написать свою собственную реализацию GridView?

Что мне нужно это умение сделать легко следующие

  • а) быть связан с IEnumerable<T>, где столбцы могут быть ограничены только определенными свойствами типа T
  • б) быть запрошены, чтобы вернуться совокупность ее строк, где каждая строка может иметь ячейку посмотрела свойство, что клетка была связана с

в основном что-то реализует следующий интерфейс будет хорошо

public interface IEasyGridBinder { 
    void Bind<T>(IEnumerable<T> bindableObjects, params string[] propertiesToBind); 
    IList<IDictionary<string, string>> Values {get;} 
} 

Так, чтобы получить это, я должен написать свой собственный EasyGridBinder, который наследуется от GridView и реализует этот интерфейс или есть очень простой способ, чтобы сделать эти вещи, которые я просто не знаком с?

P.S. Бонусные баллы, если я могу написать что-то вроде

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

Но я полагаю, я могу понять, что из себя после прочтения на выражения

последующий вопрос: Нет ли способ, чтобы получить исходные данные, которые был введен в gridview и не был преобразован в html? Если поле, полученное в качестве входных данных, содержит пустую строку, ячейка, по-видимому, содержит « », поэтому нет способа различать ввод пустой строки и пробела? Если это действительно так, то я, вероятно, вернусь к реализации большинства функций GridView.

+0

Я действительно шокирован тем, что никто не имеет хорошего решения этой проблемы. Наверное, сегодня у меня есть какая-то работа впереди, это блокировало мою демо на несколько дней. Вероятно, я выпущу его позже в коде google –

ответ

0

Я бы рекомендовал использовать методы расширения, чтобы добавить требуемое поведение. Единственным недостатком является то, что вы не можете добавить «Значения» в качестве свойства.

+0

Да, но я хочу только написать расширение, если есть действительно простой способ сделать это. Если нет ... скажем более трех строк, я мог бы также подклассом, так как мне, вероятно, придется делать и другие вещи. –

+0

Это определенно будет более 3 строк. Преимущество использования метода расширения заключается в том, что вам не нужно менять существующую разметку ASPX для замены «GridView» на «EasyGridBinder». – David

+0

Да, это то, с чего я начал, но у меня есть правило, что методы расширения должны быть не чем иным, как удобными ярлыками, любое реальное поведение там, как правило, является кодом. –

1

Если вы установите для свойства GridViews AutoGenerateColumns значение false, он будет генерировать только указанные столбцы. Вы делаете это, создавая BoundFields и добавляя их в коллекцию Gridview Columns.

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(); 

Я написал это объяснение в комментариях, но полагал, что я переместить его туда, где он был более заметным и добавьте пример кода:

Для того, чтобы выше динамического создания класса GridViewDisplayAttribute, который наследуется от атрибута. Дайте GridViewDisplayAttribute свойство HeaderText. Украсьте свойства T, определяющие HeaderText. Итерируя свойства T, создавая BoundFields для каждого украшенного свойства, используя HeaderText.

Быстрый непроверенных пример кода:

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

Хм, это будет очень полезно, мне не повезло с DataKeyNames. Благодаря! –

+0

Чтобы сделать динамическое создание класса GridViewDisplayAttribute: Атрибут. Предоставление GridViewDisplayAttribute свойства HeaderText позволит вам украсить свойства T, определяющие HeaderText. Итерируя свойства T, создавая BoundFields для каждого украшенного свойства, используя HeaderText. – ahsteele

2

LinqDataSource позволяет вам указать объект в качестве резервного хранилища для источника данных.Затем вы привязываете GridView к этому источнику данных. Это немного больше декларации в .aspx, но это меньше кода для поддержки позже, так как функция bloat приближает вас к переопределению GridView.

+0

Неплохо, но строки везде! Там идет поддержка рефакторинга. –

+0

Я имею в виду это только я, или эти операции, что я обсуждаю вещи, которые должны быть стандартными, чтобы хотеть из GridView? Принцип наименьшего удивления - неудача –

+0

По моему опыту, способ атаки MS на эти проблемы почти никогда не является наименее удивительным способом делать что-то, но в итоге это способ, которым (1) лучше всего работает с тем, что уже существует (2) заканчивается тем, что я действительно хотел, а не тем, что, как я думал, я хотел. –

Смежные вопросы