locked
Dynamically adding validation controls to a BulkGridView RRS feed

  • Question

  • User2121663738 posted

    My environment is VS 2005, .net 2.0, SQL Server 2005 and VB.net.

    I have a BulkGridView (a GridView that allows full editing) with dynamically generated columns (although I could bound a few of the first columns most of the columns are retreived dynamically because the number of columns vary from client to client). What I would like to do is dynamically add EditTemplates so I can attach the validation controls to each EditTemplate cell.

    Is this feasible? If so can anybody point in the right direction. I have found several sites about creating template columns, but none that I am positive will solve my problem.

    The sites that come closest to my needs are:

    http://www.codeproject.com/KB/aspnet/create_template_columns.aspx

    http://www.developer.com/article.php/3609991

    Thanks,

    David

    Monday, January 4, 2010 9:56 PM

All replies

  • User2121663738 posted

    I have taken a different tack in solving this problem. Instead of "templating" the fields I am trying to loop through the gridrows and assign a rangevalidator. I am getting what seems like a really simple error, but I admit I am baffled. The statement Dim cellID as string is returning Nothing; however, if I bring up Quickwatch showing gridrow.Cells.Itime(i) the ID property shows a value $ctl10$. What really is baffling is if I quickwatch gridrow.Cells.Item(i).ID it shows nothing. Any ideas?

    Also, will my approach of dynamically adding the RangeValidator work using the ID value to "hook" up the rangevalidator? I have found 1 or 2 examples of using a variable for the control ID, but it seems most examples hard-code a string value.

    If this approach will not work, does anybody have any other ideas on how to dynamically add validators without dynamically creating template fields.

                    For i = 3 To (dr.Count - 1)
                        ' Loop through each row assigning the validation rule
                        For Each gridrow As GridViewRow In GridView.Rows                          
                        ' Don't do validations on the 1st 3 columns of the grid
                        Dim cellID As String = gridrow.Cells.Item(i).ID
                        Dim timeValidation As RangeValidator = New RangeValidator()
                        If dr.Item(i).ItemArray(2).ToString() = True Then
                              ' Figure out the control to attach rule too
                              ' assign hours validation 
                              With timeValidation
                                   .ErrorMessage = "Hours must be between 0 and 40 hours"
                                   .ControlToValidate = cellID
                                   .Text = "*"
                                   .MinimumValue = 0
                                   .MaximumValue = 40
                               End With
                               'gridrow.Cells.Item(0).
                                Validations.Controls.Add(timeValidation)
                          Else
                                With timeValidation
                                    .ErrorMessage = "Amount must be between $0 and $1,000,000,000"
                                    .ControlToValidate = cellID
                                    .Text = "*"
                                    .MinimumValue = 0
                                    .MaximumValue = 1000000000
                                End With
                                Validations.Controls.Add(timeValidation)
                            End If
                            ' assign $ validation
                        Next
                    Next 
    Thanks,
    David
    Monday, January 11, 2010 9:49 PM
  • User2121663738 posted

    I am getting closer. I found a site: http://aspalliance.com/1125_Dynamically_Templated_GridView_with_Edit_Delete_and_Insert_Options.all  (the site also has comments including one where someone posted the skeleton of how to dynamically add validation controls) that satisfies most of my requirements; however, I still have one major problem.

    When I try to find the textbox control it is not being found because it is a child control. My googling indicated that I need a recursive find.  I have tried writing a recursive search, but it either "skips" the run or gives me a duplicate control name error.  Listed below is the function I modified along with the supporting code. Any help would be a big plus.

    Thanks,

    David

            Protected Overrides Sub InitializeRow(ByVal row As System.Web.UI.WebControls.GridViewRow, ByVal fields() As System.Web.UI.WebControls.DataControlField)
                MyBase.InitializeRow(row, fields)
                For Each cell As DataControlFieldCell In row.Cells
                    If cell.Controls.Count > 0 Then
                        addChangeHandler(cell.Controls)
                    End If
                Next
            End Sub
    
            Private Function FindCtrl(ByVal c As Control) As Control
                If c Is Nothing Then Return Nothing
                If (TypeOf c Is TextBox) _
                Or (TypeOf c Is DropDownList) _
                Or (TypeOf c Is CheckBox) Then Return c
                Dim results As Control
                For Each child As Control In c.Controls
                    results = FindCtrl(child)
                    If results IsNot Nothing AndAlso _
                    (TypeOf results Is TextBox _
                    Or TypeOf results Is DropDownList _
                    Or TypeOf results Is CheckBox) Then Return results
                Next
                'If we reach here, we didn't find a TextBox, DropDownList or CheckBox
                Return Nothing
            End Function
    
            Private Sub addChangeHandler(ByVal controls As ControlCollection)
                Dim ChildCtrl As Control
                For Each ctrl As Control In controls
                    ChildCtrl = FindCtrl(ctrl)
                    If TypeOf (ChildCtrl) Is TextBox Then
                        AddHandler CType(ChildCtrl, TextBox).TextChanged, AddressOf handleRowChanged
                    ElseIf TypeOf (ChildCtrl) Is DropDownList Then
                        AddHandler CType(ChildCtrl, DropDownList).SelectedIndexChanged, AddressOf handleRowChanged
                    ElseIf TypeOf (ChildCtrl) Is CheckBox Then
                        AddHandler CType(ChildCtrl, CheckBox).CheckedChanged, AddressOf handleRowChanged
                    End If
                Next
            End Sub
            Sub handleRowChanged(ByVal sender As Object, ByVal args As EventArgs)
                Dim row As GridViewRow = CType(sender, Control).NamingContainer
                If row IsNot Nothing And Not dirtyRows.Contains(row.RowIndex) Then
                    dirtyRows.Add(row.RowIndex)
                End If
            End Sub



     

    Friday, February 19, 2010 9:44 PM