C# GridView RowDataBound 不会在回发时触发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/279455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
GridView RowDataBound doesn't fire on postback
提问by Ryan Lundy
On an ASP.NET page, I have a GridView populated with the results of a LINQ query. I'm setting the DataSource in code, then calling DataBind on it. In the GridView's RowDataBound event, I'm selectively hiding links in some GridView fields based on the query results. (For instance, I hide the "Show Parent" link of the row in question has no parent row.)
在 ASP.NET 页面上,我有一个 GridView 填充了 LINQ 查询的结果。我在代码中设置 DataSource,然后在其上调用 DataBind。在 GridView 的 RowDataBound 事件中,我根据查询结果有选择地隐藏某些 GridView 字段中的链接。(例如,我隐藏了没有父行的行的“显示父级”链接。)
This works fine initially. But on postback (when I don'tcall 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?
在回发后隐藏链接的最佳方法是什么?
采纳答案by Ryan Lundy
Here's how I ended up solving this:
这是我最终解决这个问题的方法:
- 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. We'll call it
LinkVisibility
. - I created a serializable class inheriting from KeyedCollection to hold instances of the class above.
- I created a ViewState-backed property holding an instance of that collection.
- In my Search procedure (populating the GridView), I clear the collection.
- In RowDataBound, which initially shows/hides the links, I add a
LinkVisibility
instance to the collection for each row. - In Page.Load, when IsPostBack is true, I loop through the GridView rows. 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
。 - 我创建了一个继承自 KeyedCollection 的可序列化类来保存上述类的实例。
- 我创建了一个 ViewState 支持的属性,其中包含该集合的一个实例。
- 在我的搜索过程(填充 GridView)中,我清除了集合。
- 在最初显示/隐藏链接的 RowDataBound 中,我
LinkVisibility
为每一行的集合添加了一个实例。 - 在 Page.Load 中,当 IsPostBack 为 true 时,我循环遍历 GridView 行。我
LinkVisibility
通过 PK 在集合中查找每个(DataKeyNames 在 GridView 中设置),并相应地设置链接。
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.
我不知道这是最好的方法,但它确实有效,这比我尝试过的任何其他方法都多。
回答by Simon Keep
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?'.
也许这就是您需要问的问题“为什么删除的链接仍然出现在视图状态中?”。
回答by sirrocco
1)You could have a Method - ProcessDataRows() that would get called once on grid_DataBound(...). And then when you need it after PostBack.
1)你可以有一个方法 - ProcessDataRows() 可以在 grid_DataBound(...) 上调用一次。然后当你在 PostBack 之后需要它时。
And that way you process all rows when you want.
这样您就可以在需要时处理所有行。
2)You could have methods like ShowParentLink(). That are then bound to the LinkButton in the grid (if you're using an ItemTemplate) and the link would have
2)你可以有像 ShowParentLink() 这样的方法。然后将其绑定到网格中的 LinkButton(如果您使用的是 ItemTemplate)并且链接将具有
Visible='<%#ShowParentLink()%>'
回答by Jason Hernandez
A page cannot process postback events unless it is rebuilt exactlyas it was before (the postback). If you re-hide your links during the page-init, then your click events and such should fire. 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. You are rebuilding the page from the viewstate- "viewstate binding" for lack of a better word.
此外,数据 RowDataBound 不会触发,因为您不是数据绑定。由于缺少更好的词,您正在从视图状态-“视图状态绑定”重建页面。
回答by gfrizzle
Another solution is to put the logic in the LINQ query, so that you end up with a boolean LINQ field like "ShowParentLink". Then you can just bind the Visible property of the HyperLink field to that value - no RowDataBound required.
另一种解决方案是将逻辑放在 LINQ 查询中,这样您最终会得到一个布尔 LINQ 字段,如“ShowParentLink”。然后您可以将 HyperLink 字段的 Visible 属性绑定到该值 - 不需要 RowDataBound。
回答by Ryan Lundy
void Process Rows()
{
... do something
... process complete
datagrid.DataBind();
}
回答by Rob
The RowDataBound event only fires when the GridView's data changes during the postback. 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.
RowDataBound 事件仅在回发期间 GridView 的数据更改时触发。该事件是为了速度而短路的,因此它不会不必要地重新生成完全相同的数据。改为使用 RowCreated 事件来操作 HTML - 无论数据是否已更改,它都会在每次回发时触发。
回答by Sachin Amale
protected void btnHazardRating_Click(object sender, EventArgs e)
{
gvPanelRole.RowDataBound += new GridViewRowEventHandler(gvPanelRole_RowDataBound);
gvPanelRole.DataSource = dtGo;
gvPanelRole.DataBind();
ModalPopup.Show();
}