2013-04-09 5 views
1

동적으로 생성되는 데이터 바인딩 된 gridview가 있습니다. 데이터 소스는 여러 DropDownLists (객체 유형이 다릅니다)를 기반으로 객체를 반환합니다. 개체 유형에 따라 GridView는 개체에 대해서만 특정 필드를 표시해야합니다. 또한 SelectedValue가 GridView에 추가/제외 할 객체의 열을 결정하는 DropDownList가 있습니다. 여기 TemplateFields가있는 Ddynamic GridView - LifeCycle의 혼동

가의 GridView를 생성하는 방법 (내가 VB.NET에 쓰기하지만 C 번호도 매우 환영)입니다 :

Private Sub CreateGridView() 
    Dim gv As New GridView 
    With gv 
     .AllowSorting = True 
     .AutoGenerateColumns = False 
     .CssClass = "gv" 
     .EmptyDataText = "The list is empty" 
     .ID = "gv" 
     .ShowFooter = True 

     .AlternatingRowStyle.Wrap = False 
     .EditRowStyle.Wrap = False 
     .FooterStyle.Wrap = False 
     .HeaderStyle.Wrap = False 

     .SortedAscendingCellStyle.CssClass = "sortAscCell" 
     .SortedAscendingHeaderStyle.CssClass = "sortAscHeader" 
     .SortedDescendingCellStyle.CssClass = "sortDescCell" 
     .SortedDescendingHeaderStyle.CssClass = "sortDescHeader" 

     AddHandler .RowDataBound, AddressOf gv_RowDataBound 
     AddHandler .DataBound, AddressOf gv_DataBound 
     AddHandler .RowUpdating, AddressOf gv_RowUpdating 

     .DataSource = odsEquipment.Select 
     .DataKeyNames = {"equipmentID"} 
    End With 

    For Each item As Dictionary In odsDictionary.Select 
     If ddlStages.SelectedValue <> "" Then 
      If ddlStages.SelectedValue >= item.stage_id Then 
       Dim tf As New TemplateField() 
       tf.SortExpression = item.col 
       tf.HeaderTemplate = New GridViewTemplate(item.title, item.col) 
       tf.ItemTemplate = New GridViewTemplate(DataControlRowType.DataRow, item.col, item.ctrlType, item.length) 
       tf.FooterTemplate = New GridViewTemplate(DataControlRowType.Footer, item.col, item.ctrlType, item.length) 

       gv.Columns.Add(tf) 
      End If 
     End If 
    Next 

    gv.DataBind() 

    divGV.Controls.Add(gv) 
End Sub 

의 GridView 편집 모드에서 항상, 의미, 그것은 ItemTemplate을가 TexBox이 있어요/DropDownList/CheckBox. 여기에 ITemplate 클래스는 다음과 같습니다

Imports System.Data 

Public Class GridViewTemplate 
    Implements ITemplate 

    Private templateType As DataControlRowType 
    Private title As String 
    Private columnBinding As String 
    Private ctrlType As String 
    Private length As Integer 

    Public Sub New(ByVal vTitle As String, vColumnBinding As String) 
     templateType = DataControlRowType.Header 
     title = vTitle 
     columnBinding = vColumnBinding 
    End Sub 

    Public Sub New(ByVal type As DataControlRowType, ByVal vColumnBinding As String, ByVal vCtrlType As String, vLength As Integer) 
     templateType = type 
     columnBinding = vColumnBinding 
     ctrlType = vCtrlType 
     length = vLength 
    End Sub 

    Private Sub InstantiateIn(container As Control) Implements ITemplate.InstantiateIn 
     Select Case templateType 
      Case DataControlRowType.Header 
       Dim lb As New LinkButton() 
       lb.ID = "lb" + columnBinding 
       lb.CommandName = "Sort" 
       lb.CommandArgument = columnBinding 
       lb.Text = title 
       container.Controls.Add(lb) 
       Exit Select 

      Case DataControlRowType.DataRow 
       If ctrlType = "Label" Then 
        Dim lbl = New Label() 
        lbl.ID = "lbl" + columnBinding 
        AddControl(lbl, container) 
       ElseIf ctrlType = "TextBox" Then 
        Dim tb As New TextBox 
        tb.ID = "tb" + columnBinding 
        tb.MaxLength = length 
        AddControl(tb, container) 
       ElseIf ctrlType = "CheckBox" Then 
        Dim cb = New CheckBox() 
        cb.ID = "cb" + columnBinding 
        AddControl(cb, container) 
       ElseIf ctrlType = "DropDownList" Then 
        Dim ddl = New DropDownList() 
        ddl.ID = "ddl" + columnBinding 
        AddControl(ddl, container) 
       End If 
       Exit Select 

      Case DataControlRowType.Footer 
       If ctrlType = "Label" Then 
        Dim tbFrom As New TextBox() 
        tbFrom.ID = "tb" + columnBinding + "From" 
        container.Controls.Add(tbFrom) 
        Dim tbTo As New TextBox() 
        tbTo.ID = "tb" + columnBinding + "From" 
        container.Controls.Add(tbTo) 
       ElseIf ctrlType = "TextBox" Then 
        Dim tb As New TextBox 
        tb.ID = "tb" + columnBinding 
        tb.MaxLength = length 
        container.Controls.Add(tb) 
       ElseIf ctrlType = "CheckBox" Then 
        Dim cb = New CheckBox() 
        cb.ID = "cb" + columnBinding 
        container.Controls.Add(cb) 
       ElseIf ctrlType = "DropDownList" Then 
        Dim ddl = New DropDownList() 
        ddl.ID = "ddl" + columnBinding 
        AddControl(ddl, container) 
       End If 
       Exit Select 

      Case Else 
       Exit Select 
     End Select 
    End Sub 

    Private Sub AddControl(ctrl As Control, container As Control) 
     AddHandler ctrl.DataBinding, AddressOf OnDataBinding 
     container.Controls.Add(ctrl) 
    End Sub 

    Private Sub OnDataBinding(ByVal sender As Object, ByVal e As EventArgs) 
     If sender.GetType = GetType(Label) Then 
      Dim lb As Label = DirectCast(sender, Label) 
      Dim container As GridViewRow = DirectCast(lb.NamingContainer, GridViewRow) 
      lb.Text = DataBinder.Eval(container.DataItem, columnBinding).ToString 

     ElseIf sender.GetType = GetType(TextBox) Then 
      Dim tb As TextBox = DirectCast(sender, TextBox) 
      Dim container As GridViewRow = DirectCast(tb.NamingContainer, GridViewRow) 
      tb.Text = DataBinder.Eval(container.DataItem, columnBinding).ToString 

     ElseIf sender.GetType = GetType(CheckBox) Then 
      Dim cb As CheckBox = DirectCast(sender, CheckBox) 
      Dim container As GridViewRow = DirectCast(cb.NamingContainer, GridViewRow) 
      cb.Checked = DataBinder.Eval(container.DataItem, columnBinding).ToString 

     ElseIf sender.GetType = GetType(DropDownList) Then 
      Dim ddl As DropDownList = DirectCast(sender, DropDownList) 
      Dim container As GridViewRow = DirectCast(ddl.NamingContainer, GridViewRow) 
      If columnBinding = "criticalityRating" Then 
       ddl.Items.Add("") 
       For i = 1 To 4 
        ddl.Items.Add(i) 
       Next 
      ElseIf columnBinding = "property_id" Then 
       For Each p As PropertyMP In PropertyMPDB.GetProperties 
        ddl.Items.Add(New ListItem(p.propertyMP, p.property_id)) 
       Next 
      End If 
      If templateType = DataControlRowType.DataRow Then 
       ddl.SelectedValue = DataBinder.Eval(container.DataItem, columnBinding).ToString 
      End If 
     End If 
    End Sub 
End Class 

DropDownLists 자신의 ObjectDataSources에 바인딩하고 마크 업에 만들어집니다.

제가 알고 있듯이 GridView는 Page.Init의 모든 포스트 백에서 인스턴스화되어야합니다. Page.Load는 ViewState를 유지하지 않으므로 그리드 뷰를 만드는 데 늦어서 업데이트가 불가능합니다. 그러나 Init에서 만들면 DropDownLists가 아직 생성되지 않았거나 DataBound가 없으므로 선택된 값이 없습니다. DataSource에 바인딩하는 대신 Inits에서 DropDownLists를 채우려고했지만 SelectedValue를 변경할 때 ViewState 오류가 발생합니다. 내가로드에서의 GridView를 만들

은, 모든

가 가

사람이 내가의 GridView/DropDownLists 바인딩/어디를 초기화 할 알아내는 나를 도울 수 ... 업데이트하는 가장 중요한 부분을 제외하고, 완벽하게 작동? 내가 지금 사흘 동안이 고민 한 절망적 여기에 도착 :(

답변

1

해결책을 찾을 해결 방법을 발견하지 않았나요.의 GridView이하는 OnInit를 생성

, 필드의 모든 후.의 GridView 초기화에 추가됩니다 DropDownLists는 바인딩이는 ObjectDataSource를가 DropDownLists에서 매개 변수를 수신합니다.

. 반환 내가 SelectedValue를 변경 한 후, 드롭 다운리스트가 재 초기화되고 ObjectDataSource를 여전히 이전 값을 갖는 객체의 유형을 담당 한 DropDownList로가있다 잘못된 개체를 반환합니다. 여기에서 오류가 발생했습니다 - 잘못된 필드가있는 개체로 GridView를 바인딩합니다. 대신이 개체를 사용했습니다. QueryString 및 다시 게시 않았다. 다음로드시 ObjectDataSource는 GridView의 필드와 일치하는 올바른 개체를 반환합니다. 거기에서 모든 것이 부드럽습니다.