【问题标题】:How to access current row data in datasource from ITemplate.InstantiateIn如何从 ITemplate.InstantiateIn 访问数据源中的当前行数据
【发布时间】:2015-02-03 19:39:06
【问题描述】:

我有一个包含网格视图的页面我有 AutoGenerateColumns="False" 并且在我有的网格视图内 一些 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 & description 从实际数据源中的当前项目(当前行)检索属性。

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

所以我在我的页面加载 (sn-p) 中做了这样的事情

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 始终按数据源行顺序调用

参见下面的 sn-p:

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

希望这是有道理的。

谢谢。

【问题讨论】:

    标签: c# asp.net gridview


    【解决方案1】:

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

    【讨论】:

    • 谢谢,感谢您的帮助。我猜我需要每个控件的处理程序。除非有一种方法可以知道哪个控制发送者是。 NamingContainer 是网格单元吗? DataRowView 是否与网格或数据源相关,并且列是模板类的成员还是只是从 sn-p 中遗漏的东西。当然,我会亲自去研究一下,但是如果您有任何指示/注意事项,那就太好了。谢谢。
    • 在 aspx 中,硬编码模板可以访问数据源中的任何属性,即使它们未绑定到网格中的字段。
    • 我用一个更好的例子改变了我的答案
    • 谢谢,我会检查一下并标记帖子。
    • 我正在处理这个问题,并且肯定会标记已回答的帖子。有一件事让我感到困惑。我在很多地方读到过,你应该只在 page_init 中创建动态控件。我在 InstantiateIn 中执行此操作或您在绑定处理程序中执行此操作与此相反,但似乎工作正常。有风险吗?或者是否有更多关于何时必须在 page_init 中完成的信息。对我来说这是不可能的,我不知道我需要哪些以及需要多少,即使我可以稍后设置其他属性。
    猜你喜欢
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2019-09-28
    • 1970-01-01
    相关资源
    最近更新 更多