点击LinkButton获取ListView对应项DataRowView返回null问题求助
问题原因:DataItem仅在数据绑定阶段可用
你遇到的问题核心在于:ListViewDataItem.DataItem只在页面首次加载(数据绑定的那个生命周期阶段)存在,当页面回发(比如点击LinkButton触发事件)时,这个属性已经是null了。
ASP.NET Web Forms的控件数据绑定是一次性的——当你调用lv.DataBind()时,控件会生成对应的项并填充DataItem,但页面回发时,除非你在回发流程里重新执行数据绑定,否则服务器端不会保留DataItem的引用,它已经被释放了。
两种推荐的解决方案
方案1:利用ListView的DataKeyNames(最规范的做法)
这种方法不需要依赖DataItem,而是把需要的字段存储在ListView的DataKeys集合里,安全又高效:
- 先在ASPX页面的ListView标签里添加
DataKeyNames属性,指定你需要的字段(比如主键字段):
<asp:ListView ID="lv" runat="server" DataKeyNames="YourPrimaryKeyField"> <ItemTemplate> <asp:LinkButton ID="lvLB" OnClick="lvLB_OnClick" runat="server">ButtonLabel</asp:LinkButton> </ItemTemplate> </asp:ListView>
- 在后台代码里,通过
ListViewDataItem的DataItemIndex获取对应的DataKey值:
protected void lvLB_OnClick(object sender, EventArgs e) { LinkButton lb = (LinkButton)sender; ListViewDataItem dataItem = (ListViewDataItem)lb.NamingContainer; // 用NamingContainer比Parent更可靠,适配ItemTemplate里的多层容器 // 获取DataKey的值,比如主键 var keyValue = lv.DataKeys[dataItem.DataItemIndex]["YourPrimaryKeyField"]; // 如果需要完整数据,用这个key去查询数据库获取DataRowView // 示例:DataRowView rowView = GetDataRowByPrimaryKey(keyValue); }
方案2:把数据存到LinkButton的CommandArgument里
如果只需要少量字段,也可以在绑定的时候把数据直接赋值给LinkButton的CommandArgument:
- 修改ASPX里的LinkButton,绑定CommandArgument:
<asp:ListView ID="lv" runat="server"> <ItemTemplate> <asp:LinkButton ID="lvLB" OnClick="lvLB_OnClick" runat="server" CommandArgument='<%# Eval("YourTargetField") %>'>ButtonLabel</asp:LinkButton> </ItemTemplate> </asp:ListView>
- 后台直接读取CommandArgument:
protected void lvLB_OnClick(object sender, EventArgs e) { LinkButton lb = (LinkButton)sender; var fieldValue = lb.CommandArgument; // 如需完整数据,用这个值查询数据库即可 }
为什么不推荐回发时重新绑定?
如果你尝试在按钮点击事件里先重新调用lv.DataBind(),确实能让DataItem重新有值,但这会带来两个问题:
- 额外的数据库查询,降低页面性能;
- 可能导致页面状态丢失(比如用户输入的内容被重置)。
所以更推荐前面两种方案,既高效又符合Web Forms的最佳实践。
内容的提问来源于stack exchange,提问作者Adrian M
相关产品推荐
相关产品推荐

