2010-12-07 4 views
0

중첩 된 gridview 컨트롤 및 행 이벤트와 관련된 이상한 동작이 나타났습니다. 기본적으로 중첩 된 gridview 행 이벤트는 외부 그리드의 마지막 행에 있지 않으면 실행되지 않습니다.중첩 GridView 행 이벤트 판도

명시 적으로 마크 업 (예 : OnRowDeleted = "gvInner_RowDeleted") 모든 중첩있는 GridViews의 행 이벤트가 발생하지만 그것은 외부의 gridview의 마지막 행에서 중첩 된 gridview에 대한 두 번를 발생에 행 이벤트 속성을 추가하는 경우

편집 : 편집 할 수 있으므로 외부 gridview에 대해 SqlDataSource를 사용하고 있음에 유의해야합니다. 이 예제에서는 명확하지 않습니다.

마크 업 :

<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

그리고 대답은 ......

이 RowDeleted 이벤트에서 핸들 절을 제거하고 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 
0

나는 당신이하고있는 방식대로하고 있다고 생각하지 않습니다. 여기

난 당신이 시도하고 일을 할 것입니다 방법은 다음과 같습니다 더 효율적으로 렌더링으로

  1. 이 외부 데이터 바인딩 된 컨트롤에 대한 중계기를 사용하여 그것을 당신이 외부에 달성하기 위해 노력하고 같은 영향을 미칠 것 gridview 컨트롤.
  2. 코드에서, 바깥 쪽 gridview (현재 repeater) 인 데이터를 검색하고 데이터 테이블에로드하고 데이터 세트에 추가합니다. 내부 gridview의 데이터에 대해서도 동일하게 수행하십시오.
  3. 그런 다음 DataSet.Relations.Add를 사용하여 데이터 집합 내의 데이터 테이블 간의 관계를 만듭니다.
  4. 데이터 집합의 두 데이터 테이블 간의 관계를 만들면 두 번째 데이터 테이블에서 사용할 필드 (열)에 액세스 할 수 있습니다 중첩 된 (내부) gridview 컨트롤에 대한 데이터를 채 웁니다.

마크 업

<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() 
+0

감사합니다,하지만 내 간단한 예의 범위 밖에있는 내가 이런 식으로 일을 오전 이유가 . 예를 들어, 내부 및 외부 그리드 뷰 모두 SqlDataSource의 자동 편집/업데이트 기능을 이용합니다. 리피터를 사용한다면 PostBacks에 문제가있는 편집 용 컨트롤을 동적으로 추가해야합니다. – plntxt

+0

repeater 컨트롤의 하위 데이터 항목과 관계가있는 중첩 된 gridview와 함께 sqldatasource를 계속 사용할 수 있습니다. 내가 이것을 지적한 이유는 IMO가 외부 gridview 컨트롤이 아무 것도 업데이트하지 않았다고 생각했기 때문에 중첩 된 gridview 만 업데이트를 처리하고 있었기 때문입니다. 제 말은 여러분의 코드가 그 것처럼 보이는 것입니다. –

+0

아무 것도 변경하지 않았다면 outergridview의 rowIndex를 조사한 다음 중첩 된 gridview의 rowIndex를 가져와 해당 gridviewrow에서 업데이트를 실행해야합니다. –