我遇到了涉及嵌套gridview控件和行事件的奇怪行为。基本上,嵌套的gridview行事件不会触发,除非它位于外部网格的最后一行。
如果你明确地将行事件属性添加到标记(例如OnRowDeleted =“gvInner_RowDeleted”),那么行事件将触发所有嵌套的网格视图,但是它会为最后一行中的嵌套网格视图触发两次外网格视图
编辑:我应该注意到我使用SqlDataSource作为外部gridview,因为它也是可编辑的。这在示例中并不清楚。
标记:
<asp:GridView ID="gvOuter" DataSourceID="sdsOuter" runat="server" OnRowDatabound="DynamicControlAdder" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Id" ReadOnly="true" />
<asp:TemplateField>
<ItemTemplate>
<asp:UpdatePanel ID="upInner" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gvInner" DataSourceId="sdsInner" runat="server" DataKeyNames="Id" AutoGenerateColumns="false">
<Columns>
<asp:CommandField ShowDeleteButton="true" />
<asp:BoundField DataField="Id" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsInner" runat="server"
ProviderName="<%$ ConnectionStrings:YourString.ProviderName %>"
ConnectionString="<%$ ConnectionStrings:YourString %>"
SelectCommand="SELECT * FROM tblInner WHERE OuterTableKey = @OuterTableKey"
DeleteCommand="DELETE FROM tblInner WHERE Id = @Id">
<SelectParameters>
<asp:Parameter Name="OuterTableKey" DefaultValue="0" Type="Int32" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Name="Id" DefaultValue="0" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsOuter" runat="server"
ProviderName="<%$ ConnectionStrings:YourString.ProviderName %>"
ConnectionString="<%$ ConnectionStrings:YourString %>"
SelectCommand="SELECT * FROM tblOuter">
</asp:SqlDataSource>
代码:
Partial Class Testing
Inherits System.Web.UI.UserControl
Protected Sub DynamicControlAdder(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType <> DataControlRowType.DataRow Then
Exit Sub
End If
Dim s As SqlDataSource = CType(e.Row.FindControl("sdsInner"), SqlDataSource)
s.SelectParameters("OuterTableKey").DefaultValue = e.Row.DataItem("Id").ToString()
End Sub
Protected Sub gvInner_RowDeleted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeletedEventArgs) Handles gvInner.RowDeleted
//'This never fires unless it is the last row in the outer gridview
//'also, if this event is declared in the OnRowDeleted property of the inner gridview, this event fires twice if it is in the last row of the outer grid
Dim strFoo As String = "Foo"
End Sub
End Class
任何人都可以复制这个,你是如何解决它的?
答案 0 :(得分:0)
我认为你不应该按照自己的方式做你正在做的事情。
以下是我如何做你正在尝试的事情:
标记
<asp:Repeater ID="rpt1" runat="server">
<ItemTemplate>
<asp:GridView ID="gv1" runat="server" DataSource='<%# Container.DataItem.Row.GetChildRows("relation1") %>' GridLines="None" AutoGenerateColumns="false">
<columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="txt1" runat="server" Text='<%# Container.DataItem("<column>") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</columns>
</asp:GridView>
</ItemTemplate>
</asp:Repeater>
背后的代码
Dim ds As New DataSet
Dim dt1 As DataTable = obj.<method> 'Outer data
Dim dt2 As DataTable = obj.<method> 'Inner data
ds.Tables.Add(dt1)
ds.Tables.Add(dt2)
ds.Relations.Add("relation1", ds.Tables(0).Columns("<unique identifier column name>"), ds.Tables(1).Columns("<unique id column name>"), False)
rpt1.DataSource = dt1
rpt1.DataBind()
答案 1 :(得分:0)
答案是......
从RowDeleted事件中删除handles子句,并将OnRowDeleted属性设置为gvInner_RowDeleted事件。
以下更新的代码。我只希望我的生命中最后4个小时回来。
标记:
<asp:GridView ID="gvOuter" DataSourceID="sdsOuter" runat="server" OnRowDatabound="DynamicControlAdder" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Id" ReadOnly="true" />
<asp:TemplateField>
<ItemTemplate>
<asp:UpdatePanel ID="upInner" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gvInner" DataSourceId="sdsInner" runat="server" DataKeyNames="Id" OnRowDeleted="gvInner_RowDeleted" AutoGenerateColumns="false">
<Columns>
<asp:CommandField ShowDeleteButton="true" />
<asp:BoundField DataField="Id" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsInner" runat="server"
ProviderName="<%$ ConnectionStrings:YourString.ProviderName %>"
ConnectionString="<%$ ConnectionStrings:YourString %>"
SelectCommand="SELECT * FROM tblInner WHERE OuterTableKey = @OuterTableKey"
DeleteCommand="DELETE FROM tblInner WHERE Id = @Id">
<SelectParameters>
<asp:Parameter Name="OuterTableKey" DefaultValue="0" Type="Int32" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Name="Id" DefaultValue="0" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsOuter" runat="server"
ProviderName="<%$ ConnectionStrings:YourString.ProviderName %>"
ConnectionString="<%$ ConnectionStrings:YourString %>"
SelectCommand="SELECT * FROM tblOuter">
</asp:SqlDataSource>
代码:
Partial Class Testing
Inherits System.Web.UI.UserControl
Protected Sub DynamicControlAdder(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType <> DataControlRowType.DataRow Then
Exit Sub
End If
Dim s As SqlDataSource = CType(e.Row.FindControl("sdsInner"), SqlDataSource)
s.SelectParameters("OuterTableKey").DefaultValue = e.Row.DataItem("Id").ToString()
End Sub
Protected Sub gvInner_RowDeleted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeletedEventArgs)
//' Now we're talking
Dim strFoo As String = "Foo"
End Sub
End Class