如何从ITemplate.InstantiateIn访问数据源中的当前行数据

时间:2015-02-02 11:13:08

标签: c# asp.net gridview

我有一个包含gridview的页面我有AutoGenerateColumns =" False"我在gridview里面 一些asp:BoundFields和一个asp:TemplateField

<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink runat="server" NavigateUrl='<%# "~/BaseAndRepeats.aspx?id=" + Eval("ID") %>' Text="Test1"></asp:HyperLink>
<asp:HyperLink runat="server" NavigateUrl='<%# "~/BaseAndRepeats.aspx?id=" + Eval("description") %>' Text="Test2"></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>

ID&amp; description从实际数据源中的当前项(当前行)检索属性。

我真的想做这样的事情(即同一行的多个控件的外观 以编程方式依赖于该行的数据以及相关数据

所以我在页面加载(片段)中做了类似的事情

ROTAEntities1 RE = new ROTAEntities1();
List<Value_Result> _list = RE.myproc(myparam).ToList();
TemplateField tf = new TemplateField();
tf.ItemTemplate = new OwnedEventsPage.MyTemplate(RE, _list);
GridView1.Columns.Add(tf);
this.GridView1.DataSource = _list;
this.GridView1.DataBind();

但是在InstantiateIn中我似乎找不到通过容器访问当前行数据的方法 在网格或数据源中。所以我将数据源和我可能需要的任何其他内容传递给构造和模板上的模板 使用成员int来跟踪行。

但是这意味着模板和InstantiateIn不成立 他们自己稳定,但依赖于一些假设

  • 模板是新构建的,并在绑定之前添加
  • 在此
  • 后直接发生绑定
  • 始终以数据源行顺序调用InstantiateIn

请参阅以下代码段:

private class MyTemplate : ITemplate
{
    ROTAEntities1 RE;
    int rowCount = 0;
    List<ListOwnedBaseEvents_Result> mylist;

    public MyTemplate(ROTAEntities1 _re, List<Value_Result> _list)
    {
        RE = _re;
        mylist = _list;

    }
    public void InstantiateIn(System.Web.UI.Control container)
    {
        // can obtain the current DataControlFieldCell but cannot seem to access the
        // current grid or datasource row
        DataControlFieldCell dcfc = (DataControlFieldCell)container;

        int id = mylist[rowCount].ID;
        rowCount++;

        // then I go on to create controls and add to the container
        // making use of id, mylist and other related data entities in RE
        // 
        ...
    }

有没有办法可以让InstantiateIn独立知道当前的数据源行是什么 因为它正在构建和添加控件,就像我有效地使用标记一样 aspx。我认为这会更安全。

希望这是有道理的。

感谢。

1 个答案:

答案 0 :(得分:0)

我找不到对此的确认,但我相信在数据绑定之前调用InstantiateIn,因此您当时没有关于数据的信息。

您可以做的是将事件处理程序附加到容器的DataBind事件,并在处理程序上相应地创建对象。

public class myTemplate : ITemplate
{

    public void InstantiateIn(Control container)
    {
        container.DataBinding +=container_DataBinding;
    }

    private void container_DataBinding(object sender, EventArgs e)
    {
        //get current data item associated with the row where the template is
        var data = DataBinder.GetDataItem(((Control)sender).NamingContainer);

        //I'm supposing I bound an object collection with a property Name, but this is generic like you do with Eval in aspx.
        var fieldValue = DataBinder.Eval(data, "Name");

        //here you can use the field value to add controls to the container, just cast the sender to a Control type
    }
}