简体   繁体   English

GridView RowDataBound不会在回发时触发

[英]GridView RowDataBound doesn't fire on postback

On an ASP.NET page, I have a GridView populated with the results of a LINQ query. 在ASP.NET页面上,我有一个填充了LINQ查询结果的GridView。 I'm setting the DataSource in code, then calling DataBind on it. 我在代码中设置DataSource,然后在其上调用DataBind。 In the GridView's RowDataBound event, I'm selectively hiding links in some GridView fields based on the query results. 在GridView的RowDataBound事件中,我根据查询结果选择性地隐藏某些GridView字段中的链接。 (For instance, I hide the "Show Parent" link of the row in question has no parent row.) (例如,我隐藏有问题的行的“显示父级”链接没有父行。)

This works fine initially. 这最初工作正常。 But on postback (when I don't call DataBind, but the GridView stays populated through ViewState), the data displays, but the RowDataBound event (obviously) doesn't fire, and my links don't get hidden. 但是在回发时(当我调用DataBind,但GridView通过ViewState保持填充时),数据显示,但RowDataBound事件(显然)不会触发,并且我的链接不会被隐藏。

What's the best way to get the links to be hidden after a postback? 回发后隐藏链接的最佳方法是什么?

Here's how I ended up solving this: 这是我最终解决这个问题的方法:

  1. I created a serializable class with readonly properties: PK of a row, and a boolean for each link indicating whether it's enabled or not. 我创建了一个具有readonly属性的可序列化类:行的PK,以及指示是否启用的每个链接的布尔值。 We'll call it LinkVisibility . 我们称之为LinkVisibility
  2. I created a serializable class inheriting from KeyedCollection to hold instances of the class above. 我创建了一个继承自KeyedCollection的可序列化类来保存上面类的实例。
  3. I created a ViewState-backed property holding an instance of that collection. 我创建了一个ViewState支持的属性,其中包含该集合的实例。
  4. In my Search procedure (populating the GridView), I clear the collection. 在我的搜索过程(填充GridView)中,我清除了该集合。
  5. In RowDataBound, which initially shows/hides the links, I add a LinkVisibility instance to the collection for each row. 在最初显示/隐藏链接的RowDataBound中,我将LinkVisibility实例添加到每行的集合中。
  6. In Page.Load, when IsPostBack is true, I loop through the GridView rows. 在Page.Load中,当IsPostBack为true时,我循环遍历GridView行。 I look up the LinkVisibility for each one by PK in the collection (DataKeyNames is set in the GridView), and I set the links accordingly. 我通过集合中的PK查找每个的LinkVisibility (在GridView中设置DataKeyNames),然后相应地设置链接。

I don't know that this is the best way to do this, but it certainly does work, which is more than I can say for anything else I've tried. 我不知道这是最好的方法,但它确实有效,这比我试过的任何其他事情都要多。

The RowDataBound event only fires when the GridView's data changes during the postback. RowDataBound事件仅在回发期间GridView的数据发生更改时触发。 The event is short-circuited for speed so it's not re-generating the exact same data unnecessarily. 事件因速度而短路,因此不会不必要地重新生成完全相同的数据。 Use the RowCreated event to manipulate the HTML instead - it fires on every postback regardless of whether the data has changed. 使用RowCreated事件来操纵HTML - 无论数据是否已更改,它都会在每次回发时触发。

1) You could have a Method - ProcessDataRows() that would get called once on grid_DataBound(...). 1)你可以有一个方法 - 在Grid_DataBound(...)上调用一次的ProcessDataRows()。 And then when you need it after PostBack. 然后在PostBack之后需要它的时候。

And that way you process all rows when you want. 这样您就可以在需要时处理所有行。

2) You could have methods like ShowParentLink(). 2)您可以使用ShowParentLink()等方法。 That are then bound to the LinkButton in the grid (if you're using an ItemTemplate) and the link would have 然后将其绑定到网格中的LinkBut​​ton(如果您使用的是ItemTemplate)并且该链接将具有

Visible='<%#ShowParentLink()%>'

I would have expected the viewstate to also reflect the fact that you have removed some of the links (assuming that they were removed before viewstate was saved). 我原本期望viewstate也反映出你已经删除了一些链接的事实(假设它们在保存viewstate之前被删除了)。

Maybe thats the question you need to ask 'why do the removed links still appear in viewstate?'. 也许这就是你需要问'为什么删除的链接仍然出现在viewstate?'的问题。

A page cannot process postback events unless it is rebuilt exactly as it was before (the postback). 页面无法处理回发事件,除非它与以前完全重建(回发)。 If you re-hide your links during the page-init, then your click events and such should fire. 如果您在page-init期间重新隐藏链接,则应触发您的点击事件等。 Unfortunately, without seeing some sample code I can't get more specific. 不幸的是,没有看到一些示例代码,我无法更具体。

Also the data RowDataBound does not fire because you are not data binding. 此外,数据RowDataBound不会触发,因为您不是数据绑定。 You are rebuilding the page from the viewstate- "viewstate binding" for lack of a better word. 您正在从viewstate重新构建页面 - “viewstate binding”缺少更好的单词。

Another solution is to put the logic in the LINQ query, so that you end up with a boolean LINQ field like "ShowParentLink". 另一种解决方案是将逻辑放在LINQ查询中,以便最终得到一个类似“ShowParentLink”的布尔LINQ字段。 Then you can just bind the Visible property of the HyperLink field to that value - no RowDataBound required. 然后,您可以将HyperLink字段的Visible属性绑定到该值 - 不需要RowDataBound。

void Process Rows()
{
    ... do something
    ... process complete
    datagrid.DataBind();
}
protected void btnHazardRating_Click(object sender, EventArgs e)
{
    gvPanelRole.RowDataBound += new GridViewRowEventHandler(gvPanelRole_RowDataBound);

    gvPanelRole.DataSource = dtGo;
    gvPanelRole.DataBind();
    ModalPopup.Show();

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM