我没有过多地使用过GridView,在探索过它之后,发现它比我需要的更复杂,但却缺少一些我希望它具有的非常基本的功能。毫无疑问,它的实现是有意义的,因为其90%的时间目的是绑定到数据集,特别是在声明性地执行此操作时,但我打算将其绑定到代码中的IEnumerable<T>
。
我需要的是能够轻松完成以下任务
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 :(得分: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)
我建议使用扩展方法添加所需的行为。唯一的缺点是你不能将“值”添加为属性。