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

How to access current row data in datasource from ITemplate.InstantiateIn

我有一个包含 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 和描述从实际数据源中的当前项(当前行)检索属性。

我真的很想做这样的事情(即同一行上的多个控件,其外观 取决于该行的数据以及相关数据)以编程方式

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

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不成立 自身稳定,但取决于许多假设

请参阅下面的代码段:

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。我认为这样会更安全。

希望这是有道理的。

谢谢。

我找不到对此的确认,但我相信 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
    }
}