我应该编写自己的GridView实现吗?

时间:2009-03-11 21:42:15

标签: .net asp.net gridview

我没有过多地使用过GridView,在探索过它之后,发现它比我需要的更复杂,但却缺少一些我希望它具有的非常基本的功能。毫无疑问,它的实现是有意义的,因为其90%的时间目的是绑定到数据集,特别是在声明性地执行此操作时,但我打算将其绑定到代码中的IEnumerable<T>

我需要的是能够轻松完成以下任务

  • a)绑定到IEnumerable<T>,其中列可以仅限于T类型的某些属性
  • b)查询返回其行的集合,其中每行可以通过单元格绑定的属性查找单元格

基本上实现以下界面的东西会很好

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的大部分功能。

3 个答案:

答案 0 :(得分:2)

LinqDataSource允许您将对象指定为数据源的后备存储。然后,您将GridView绑定到该数据源。它在.aspx中的声明要多一些,但随着功能膨胀使你越来越接近重新实现GridView,它的维护代码越来越少。

答案 1 :(得分: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();

我在评论中写了这个解释,但想到我会把它移到更明显的地方并添加一个代码示例:

要使上面的动态创建一个继承自Attribute的GridViewDisplayAttribute类。为GridViewDisplayAttribute提供HeaderText属性。装饰T的属性,指定HeaderText。通过迭代使用HeaderText为每个修饰属性创建BoundFields的T的属性。

快速未经测试的代码示例:

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

答案 2 :(得分:0)

我建议使用扩展方法添加所需的行为。唯一的缺点是你不能将“值”添加为属性。