【问题标题】:call RowDataBound from another function从另一个函数调用 RowDataBound
【发布时间】:2016-02-16 14:49:07
【问题描述】:

我有 2 个网格视图。第一个网格有一个按钮,当单击该按钮时,它将根据单击的按钮的 id 填充第二个网格。

然后我在 RowDataBound 函数中有代码来根据所选行显示网格。但问题是代码在填充函数之前自动运行 RowDataBound。所以第二个网格没有显示。

GridView 的代码:

<asp:GridView  style="width:75%"  
                        ID="gvCVRT" 
                        ShowHeaderWhenEmpty="true"
                        CssClass="tblResults" 
                        runat="server" 
                        OnRowDataBound="gvCVRT_RowDataBound"  
                        OnSelectedIndexChanged="gridviewParent_SelectedIndexChanged"                           
                        DataKeyField="ID" 
                        DataKeyNames="ChecklistID"
                        AutoGenerateColumns="false"
                        allowpaging="false"
                        AlternatingRowStyle-BackColor="#EEEEEE">
                        <HeaderStyle CssClass="tblResultsHeader" />
                        <Columns>
                            <asp:BoundField DataField="ChecklistID" HeaderText="ID"  ></asp:BoundField> 
                            <asp:CommandField ShowSelectButton="True" HeaderText="Select" />
                            <asp:BoundField DataField="ChecklistDate" HeaderText="Checklist Date" dataformatstring="{0:dd/MM/yyyy}"></asp:BoundField>
                            <asp:BoundField DataField="User" HeaderText="User" ></asp:BoundField>
                            <asp:BoundField DataField="Note" HeaderText="Note" ></asp:BoundField>

                        </Columns>
                    </asp:GridView> 

后面的代码:

protected void gvCVRT_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        lookupCVRT work = (lookupCVRT)e.Row.DataItem;
        GridView gv = sender as GridView;

        if (work.ID != null)
        {
            int index = gv.Columns.HeaderIndex("Select");
            if (index > -1)
            {
                e.Row.Cells[index].Attributes.Add("class", "gvCVRTRow");
                e.Row.Cells[index].ToolTip = "Click here to Edit Checklist";
            }
        }
    }
}

选择按钮的代码:

protected void gridviewParent_SelectedIndexChanged(object sender, EventArgs e)
{
    List<lookupCVRT> workDetails = lookupCVRT.GetChecklistItemsByChecklistID(Company.Current.CompanyID, ParentID.ToString(), gvCVRT.SelectedDataKey.Value.ToString());
    gvCVRTDetails.DataSource = workDetails;
    gvCVRTDetails.DataBind();
    FireJavascriptCallback("setArgAndPostBack ();");
}

所以问题是当我单击网格中的“选择”按钮时,它首先运行RowDataBound,然后运行gridviewParent_SelectedIndexChanged,但我需要先运行gridviewParent_SelectedIndexChanged。我可以从gridviewParent_SelectedIndexChanged 调用RowDataBound 函数吗?

Page_Load 函数:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            GetChecklistID = "";
            if (ParentID.HasValue)
            {
                ViewState["ParentID"] = ParentID;

                List<lookupCVRT> work = lookupCVRT.GetCVRTItems(Company.Current.CompanyID, ParentID.ToString());
                ViewState["CVRT"] = work;
                gvCVRT.DataSource = work;
                gvCVRT.DataBind();

            }
        }
        else
        {
            if (ViewState["ParentID"] != null)
            {
                ParentID = (int?)ViewState["ParentID"];
                List<lookupCVRT> work = ViewState["CVRT"] as List<lookupCVRT>;
                gvCVRT.DataSource = work;
                gvCVRT.DataBind();

            }
        }
    }

【问题讨论】:

  • 您能否将您的 Page_Load 方法和所有其他包含下降到 DataBind() 的方法发布?
  • @Markus 将 Page_Load 代码添加到我的问题中。这是唯一调用 DataBind 的地方。当我单击选择时,它进入方法的else 部分
  • 谢谢;我想我已经发现了问题;请查看我的更新答案。
  • @Markus 好的,我已经更新了我的代码,但同样的事情仍在发生。它首先运行OnRowDataBound ,然后运行gridviewParent_SelectedIndexChanged函数
  • 你能在调试器中跟踪代码吗?在您找到的每次调用 DataBind 时设置一个断点。 RowDataBound 是调用 DataBind 的结果。

标签: c# asp.net gridview


【解决方案1】:

只有在调用了GridViewDataBind 方法时,才会调用OnRowDataBound 事件。

在您的特定情况下,问题出在Page.IsPostBack 条件的else 分支中的Page_Load 中:

 else
{
    if (ViewState["ParentID"] != null)
    {
        ParentID = (int?)ViewState["ParentID"];
        List<lookupCVRT> work = ViewState["CVRT"] as List<lookupCVRT>;
        gvCVRT.DataSource = work;
        gvCVRT.DataBind();

    }
}

此代码针对每个回发运行。除非您在代码中的其他位置重置 ViewState["ParentID"],否则在每次回发时,您都会再次绑定 GridView gvCVRT。这就是调用RowDataBound 的原因。完成Page_Load 后,页面调用其他事件处理程序,在您的情况下为gridviewParent_SelectedIndexChanged

为了解决这个问题,您需要更改 Page_Load 处理程序中的代码,以便不会调用 DataBind 进行回发:

// field moved to class level so that you can access this variable instead of a DataRow in gvCVRT
private List<lookupCVRT> work;

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        GetChecklistID = "";
        if (ParentID.HasValue)
        {
            ViewState["ParentID"] = ParentID;

            work = lookupCVRT.GetCVRTItems(Company.Current.CompanyID, ParentID.ToString());
            ViewState["CVRT"] = work;
            gvCVRT.DataSource = work;
            gvCVRT.DataBind();

        }
    }
    else
    {
        if (ViewState["ParentID"] != null)
        {
            ParentID = (int?)ViewState["ParentID"];
            work = ViewState["CVRT"] as List<lookupCVRT>;
        }
    }
}

问题的根本原因是您需要回发请求中的数据,并且您将这些数据放入ViewState["CVRT"],而不是重新请求数据。在 Web 应用程序中,为新请求再次读取数据是很常见的。因此,您可能会考虑是否真的需要将数据放入 ViewState,或者是否可以在从数据源回发时请求它们。

将数据放入 ViewState 会增加传输到客户端的页面大小(基本上,您拥有 GridView 的 HTML,此外,您还拥有 ViewState 中的数据)。因此,在大多数情况下,重新请求它们会是更好的方法。

【讨论】:

  • 但是Gridview 在单击选择时被绑定,因为我需要从所选行中获取 ID:gvCVRT.SelectedDataKey.Value.ToString()。我无法从 page_load 执行此操作,因为我还没有 ID。
  • @user123456789:是的,我明白这一点。我再次阅读了您的问题,并且对控件和事件处理程序的名称越来越感到困惑。澄清一下:您有一个 GridView gvCVRT,它是具有事件处理程序 gridviewParent_SelectedIndexChangedgvCVRT_RowDataBound 的父级。然后有一个子 GridView gvCVRTDetails,但问题中没有提到子 GridView 的事件处理程序。 RowDataBound 是指 gvCVRT_RowDataBound 还是子 GridView 的处理程序?
  • @user123456789:但是,RowDataBound 仅在调用 DataBind 后运行。因此,检查代码中对DataBind 的所有调用以及它们是否在正确的位置将是一个很好的步骤。例如,如果父 GridView 在 Page_Load 中绑定数据,则其 gvCVRT_RowDataBound 将在 gridviewParent_SelectedIndexChanged 之前运行,并且很可能会破坏选择。
  • 是的,父 GridView 在 Page_Load 中是数据绑定的。当从父 GridView 中单击选择时,它会再次运行RowDataBound,然后运行gridviewParent_SelectedIndexChanged 。但我需要先运行gridviewParent_SelectedIndexChanged 来绑定网格,然后它才会尝试显示它
  • @user123456789 在Page_Load 中是否有检查Page.IsPostBack 周围的gvCVRT.DataBind() 类似于我的答案?如果不是,则gvCVRTPage_Load 中每个请求的数据绑定。由于DataBind()Page_Load 中被调用,gvCVRT_RowDataBound 在处理任何其他事件之前运行,因此也在gridviewParent_SelectedIndexChanged 之前运行。
【解决方案2】:

我不知道你为什么更喜欢使用gridviewParent_SelectedIndexChanged 然后grdParent_RowDataBound ...我为你创建了一个简单的解决方案..它可以帮助你..

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <div>
        <label>Parent Grid</label>
        <asp:GridView ID="grdParent" runat="server" AutoGenerateColumns="false" 
            DataKeyField="Id" OnRowDataBound="grdParent_RowDataBound" OnRowCommand="grdParent_RowCommand">
            <Columns>
                <asp:BoundField DataField="Name" HeaderText="Name" />                
                <asp:ButtonField CommandName="Details"  HeaderText="Select" Text="Hello" ButtonType="Link" />
            </Columns>
        </asp:GridView>
    </div>
    <div>
         <label>child Grid</label>
        <asp:GridView ID="grdChild" runat="server" AutoGenerateColumns="false"
            DataKeyNames="ChildId" OnRowDataBound="grdChild_RowDataBound">
            <Columns>
                <asp:BoundField DataField="Name" />
                <asp:BoundField DataField="Roll" />                
                <asp:ImageField HeaderText="Image" />
            </Columns>
        </asp:GridView>
    </div>
    </div>
    </form>
</body>
</html>

代码隐藏

public partial class Default2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            List<ParentClass> pList = new List<ParentClass>()
            {
                new ParentClass{Id=5, Name="V"},
                new ParentClass{Id=6,Name="VI"},
                new ParentClass{Id=7,Name="VII"},
                new ParentClass{Id=8,Name="VIII"},
                new ParentClass{Id=9,Name="IX"},
                new ParentClass{Id=10,Name="X"},
            };

            grdParent.DataSource = pList;
            grdParent.DataBind();
        }
    }

    protected void grdParent_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.DataItem == null || e.Row.RowType != DataControlRowType.DataRow)
        {
            return;
        }

        ParentClass p = e.Row.DataItem as ParentClass;

        var btn = e.Row.Cells[1].Controls[0] as LinkButton;
        btn.CommandArgument = p.Id.ToString();
    }

    protected void grdParent_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        int parentId = Convert.ToInt32(e.CommandArgument);

        var releventStudents = GetRepositary().FindAll(i => i.ParentId == parentId);

        grdChild.DataSource = releventStudents;
        grdChild.DataBind();

    }

    protected void grdChild_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.DataItem == null || e.Row.RowType != DataControlRowType.DataRow)
        {
            return;
        }

        //lookupCVRT work = (lookupCVRT)e.Row.DataItem;
        //GridView gv = sender as GridView;

        //if (work.ID != null)
        //{
        //    int index = gv.Columns.HeaderIndex("Select");
        //    if (index > -1)
        //    {
        //        e.Row.Cells[index].Attributes.Add("class", "gvCVRTRow");
        //        e.Row.Cells[index].ToolTip = "Click here to Edit Checklist";
        //    }
        //}         
    }

    private List<ChildClass> GetRepositary()
    {
        List<ChildClass> allChild = new List<ChildClass>();
        Random r = new Random();

        for (int i = 0; i < 50; i++)
        {
            ChildClass c = new ChildClass
            {
                ChildId = i,
                ParentId = r.Next(5, 10),
                Name = "Child Name " + i,
                Roll = i
            };

            allChild.Add(c);
        }

        return allChild;
    }
}

public class ParentClass
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ChildClass
{
    public int ParentId { get; set; }
    public int ChildId { get; set; }
    public int Roll { get; set; }
    public string Name { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 2022-12-05
    • 2016-07-14
    • 2016-04-06
    相关资源
    最近更新 更多