[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Problems with OnItemUpdating for DetailsView

Posted on 2009-05-14
1
Medium Priority
?
597 Views
Last Modified: 2012-05-07
My issue is similar to http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_23004459.html, but in my case I'm dynamically adding TemplateFields to the DetailsView instead of simple BoundFields.

I'm still working with TextBox controls for now, but when I get this to work I need to be able to use this mechanism with other webcontrols like DropDownList etc. as well.

The textboxes show up fine in the detailsview and display the value from the datasource (= a datatable). But when capturing the newly entered values in OnItemUpdating, the Fields collection is empty and so are e.Keys and e.NewValues .
Partial Public Class wsExtendedDetailsView
    Inherits System.Web.UI.WebControls.DetailsView
 
    Private _oSystem As New wsSystem
    Private _oDP As New wsDataProvider
 
#Region "Overrides"
 
    Protected Overrides Sub OnItemCreated(ByVal e As System.EventArgs)
 
        'Be sure to call the base class's OnItemCreated method!
        MyBase.OnItemCreated(e)
 
        If Me.Rows.Count > 0 Then
            ' swap each header <td> cell for a <th> cell
            For Each l_oRow As DetailsViewRow In Me.Rows
                If l_oRow.RowType = DataControlRowType.DataRow Then
                    Dim l_oTD As DataControlFieldCell = l_oRow.Cells(0)
                    If l_oTD.Controls.Count = 0 Then
                        Dim l_oTH As DataControlFieldHeaderCell = New DataControlFieldHeaderCell(l_oTD.ContainingField)
                        l_oTH.Text = l_oTD.Text
                        l_oTH.Attributes.Add("scope", "row")
 
                        ' add the new th and remove the old td
                        l_oRow.Cells.RemoveAt(0)
                        l_oRow.Cells.AddAt(0, l_oTH)
                    End If
                End If
            Next
        End If
 
    End Sub
 
    Protected Overrides Function CreateFieldSet(ByVal dataItem As Object, ByVal useDataSource As Boolean) As System.Collections.ICollection
 
        Dim l_aFields As New ArrayList()
        For Each l_oField As DataControlField In MyBase.CreateFieldSet(dataItem, useDataSource)
            l_aFields.Add(l_oField)
        Next
 
        ' we have a predefined set of database columns to display
        For Each l_sColumn As String In Me.DisplayColumns
 
            ' see if the column exists in the database
            If _oDP.IsColumn(Me.PrimaryTable, l_sColumn) Then
 
                ' determine the language specific string to use for HeaderText
                Dim l_sHeader As String = wsLanguage.GetExternalDataForLanguage(Me.PrimaryTable, l_sColumn, "columnname")
                If wsUtils.IsEmpty(l_sHeader) And l_sColumn.ToUpper = "ID" Then
                    l_sHeader = l_sColumn
                End If
 
                ' 
                Dim l_oColumn As New TemplateField()
                l_oColumn.HeaderText = l_sHeader & " : "
                l_oColumn.ItemTemplate = New wsDetailsViewTemplate("literal", l_sColumn)
                If l_sColumn.ToUpper = "ID" Then
                    ' primary key always just a Literal (and thus never editable)
                    l_oColumn.EditItemTemplate = New wsDetailsViewTemplate("literal", l_sColumn)
                    l_oColumn.InsertItemTemplate = New wsDetailsViewTemplate("literal", l_sColumn)
                Else
                    l_oColumn.EditItemTemplate = New wsDetailsViewTemplate("textbox", l_sColumn)
                    l_oColumn.InsertItemTemplate = New wsDetailsViewTemplate("textbox", l_sColumn)
                End If
 
                ' add the new TemplateField to the Fields collection
                l_aFields.Add(l_oColumn)
 
            End If
 
        Next
 
        Return l_aFields
 
    End Function
 
    Protected Overrides Sub OnItemUpdating(ByVal e As System.Web.UI.WebControls.DetailsViewUpdateEventArgs)
 
        Dim l_aColumns As New Hashtable, l_iIndex As Integer = 0
 
        If Me.Fields.Count > 0 Then
 
            For l_iI As Integer = 0 To Me.Rows.Count - 1
                Dim l_oNormal As DataControlFieldCell = Me.Rows(l_iI).Cells(0)
                Me.Fields(l_iI).ExtractValuesFromCell(e.Keys, l_oNormal, DataControlRowState.Normal, True)
                Dim l_oEdit As DataControlFieldCell = Me.Rows(l_iI).Cells(1)
                Me.Fields(l_iI).ExtractValuesFromCell(e.NewValues, l_oEdit, DataControlRowState.Edit, False)
            Next
 
            ' the following is for testing only... these always turn up empty
            For Each l_sKey As String In e.Keys
                Dim l_sKeyValue = e.Keys(l_sKey)
            Next
            For Each l_sKey As String In e.NewValues
                Dim l_sNewValue = e.NewValues(l_sKey)
            Next
 
        End If
 
        'Be sure to call the base class's OnItemUpdating method!
        MyBase.OnItemUpdating(e)
 
    End Sub
 
#End Region
 
#Region "Custom properties (using ViewState)"
...
#End Region
 
End Class
 
==================================================================
 
Public Class wsDetailsViewTemplate
    Implements ITemplate
 
    Dim _sControlType As String
    Dim _sColumnName As String
 
    Sub New(ByVal p_sControlType As String, ByVal p_sColumn As String)
        _sControlType = p_sControlType
        _sColumnName = p_sColumn
    End Sub
 
    Sub InstantiateIn(ByVal p_oContainer As Control) _
        Implements ITemplate.InstantiateIn
 
        Select Case _sControlType.ToLower
            Case "textbox"
                Dim l_oTextBox As New TextBox
                l_oTextBox.ID = _sColumnName
                AddHandler l_oTextBox.DataBinding, AddressOf OnDataBinding
                p_oContainer.Controls.Add(l_oTextBox)
            Case Else
                ' implement Literal as default
                Dim l_oLiteral As New Literal
                l_oLiteral.ID = _sColumnName
                AddHandler l_oLiteral.DataBinding, AddressOf OnDataBinding
                p_oContainer.Controls.Add(l_oLiteral)
        End Select
 
    End Sub
 
    Protected Sub OnDataBinding(ByVal sender As Object, ByVal e As System.EventArgs)
 
        Dim l_oControl As Object, l_oContainer As wsExtendedDetailsView
        Select Case _sControlType.ToLower
            Case "textbox"
                l_oControl = TryCast(sender, TextBox)
                l_oContainer = TryCast(l_oControl.NamingContainer, wsExtendedDetailsView)
                l_oControl.Text = DataBinder.Eval(l_oContainer.DataItem, _sColumnName)
            Case Else
                ' implement Literal as default
                l_oControl = TryCast(sender, Literal)
                l_oContainer = TryCast(l_oControl.NamingContainer, wsExtendedDetailsView)
                l_oControl.Text = DataBinder.Eval(l_oContainer.DataItem, _sColumnName)
        End Select
 
    End Sub
 
End Class

Open in new window

0
Comment
Question by:MarjaR
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 
LVL 1

Accepted Solution

by:
MarjaR earned 0 total points
ID: 24392903
Found a solution that works for me:

I've now implemented a custom GetValues function which gets called in OnItemUpdating (see below)


    Protected Function GetValues() As Hashtable
        Dim l_aValues As New Hashtable
        For Each l_oRow As DetailsViewRow In Me.Rows
            ' only look at DataRow
            If l_oRow.RowType = DataControlRowType.DataRow Then
                Dim l_oCell As DataControlFieldCell = CType(l_oRow.Cells(0), DataControlFieldCell)
                If l_oCell.ContainingField.ShowHeader Then
                    ' if we are showing the header for this row then the data is in the adjacent cell
                    l_oCell = CType(l_oRow.Cells(1), DataControlFieldCell)
                End If
                If l_oCell.Controls.Count > 0 Then
                    ' we do have some controls in this cell
                    ' capture their values
                    For Each l_oControl As Control In l_oCell.Controls
                        Dim l_sID As String = l_oControl.ID
                        If l_sID.ToUpper <> "ID" Then
                            Dim l_sValue As String = ""
                            ' 1st see if it is a Literal
                            If TypeOf l_oControl Is Literal Then
                                Dim l_oLiteral As Literal = CType(l_oControl, Literal)
                                l_sValue = l_oLiteral.Text
                            ElseIf TypeOf l_oControl Is TextBox Then
                                Dim l_oTextBox As TextBox = CType(l_oControl, TextBox)
                                l_sValue = l_oTextBox.Text
                            End If
                            l_aValues.Add(l_sID, l_sValue)
                        End If
                    Next
                End If
            End If
        Next
        Return l_aValues
    End Function
 
    Protected Overrides Sub OnItemUpdating(ByVal e As System.Web.UI.WebControls.DetailsViewUpdateEventArgs)
 
        _aControlValues = GetValues()
 
        If _aControlValues.Count > 0 Then
            ' updated record with new values
            Dim l_iID As Long = Me.PrimaryKeyValue
            l_iID = _oDP.EditRecord(l_iID, Me.PrimaryTable, _aControlValues)
        End If
 
        'Be sure to call the base class's OnItemUpdating method
        MyBase.OnItemUpdating(e)
 
    End Sub

Open in new window

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Problem Hi all,    While many today have fast Internet connection, there are many still who do not, or are connecting through devices with a slower connect, so light web pages and fast load times are still popular.    If your ASP.NET page …
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question