2010年5月12日 星期三

IQueryable 的資料,如何在 GridView 的RowDataBound 事件中處理

問題

有讀者問到,以往在 GridView 的資料,常用的是 Datatable 來繫結。如下

GridView1.DataSource = myDataTable;
GridView1.DataBind();

而在 GridView的 RowDataBound 事件中,就可以使用 DataRow 來處理 RowDataBound 細節。如下

if (e.Row.RowType == DataControlRowType.DataRow)
{
    DataRow row = e.Row.DataItem as DataRow;
    string name = row["Name"].ToString();
    ...
}

在使用了 LINQ to SQL 或 Entity Framework 後,就不鼓勵使用 DataSet or DataTable 等資料物件,而是 Entity 了。但這樣一來,繫結到 Anonymous type 的物件,在RowDataBound 的事件要如何指定型別呢?如下例

if (e.Row.RowType == DataControlRowType.DataRow)
{
    DataRow row = e.Row.DataItem as WHAT_TYPE; //不知道要指定什麼型別
    string name = row["Name"].ToString();
    ...
}

解答

Anonymous Type 同一個 Method 中還可以看的到型別,在其他 Method 中,就沒有型別名稱可以使用了,這也是Anonymous Type 特殊的地方。因此,上面的問題中的 WHAT_TYPE 是找不到名稱的。

但我們的目的是找到繫結資料的內容,而非型別。因此使用 Reflection 來找資料內容即可。藉由 DataBinder.Eval 的幫助,我們可以輕易的得到資料內容。如下例

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
  if (e.Row.RowType == DataControlRowType.DataRow)
  {
    string name = DataBinder.Eval(e.Row.DataItem, "Name") as string;
    int id = (int)DataBinder.Eval(e.Row.DataItem, "Id");
    if (id % 2 == 0)
      e.Row.Cells[1].Text = string.Format("{0} is even", name);
  }
}
範例程式可在這裡下載

沒有留言:

Share with Facebook