Donnerstag, 5. April 2012

ViewState die Zweite...

Man nehme ein Grid und deaktiviere den ViewState für dieses, da das bekannte Anwachsen des Selbigen immer wieder zu Performance-Problemem führt, insbesondere wenn die Anwendung über eine schwachbrüstige Internetleitung aufgerufen wird.
Führt man nun über ein weiteres Steuerelement der Seite eine Aktion aus, die einen Postback mit sich bringt, wird das Grid neu an die Datenquelle gebunden und zuvor gemachte Eingaben sind verloren. Also doch der ViewState? Nein, lieber nicht. Um dieses Problem (was eigentlich keines ist) zu umschiffen habe ich folgende Klasse erstellt, welche vorhandene, aber nicht gespeicherte Angaben des Grids in der entsprechenden Datenquelle, dem DataView vornimmt, ganz ohne Viewstate.

Public Class UpdateView
        Private _grid As RadGrid
        Private _assignments As SortedDictionary(Of String, String) = New SortedDictionary(Of String, String)
        Public Property Assignments As SortedDictionary(Of String, String)
            Get
                Return _assignments
            End Get
            Set(value As SortedDictionary(Of String, String))
                _assignments = value
            End Set
        End Property

        Public ReadOnly Property Grid As RadGrid
            Get
                Return _grid
            End Get
        End Property

        Public Sub New(ByVal grid As RadGrid)
            Me._grid = grid
        End Sub

        Public Sub Update(ByRef dataView As DataView)
            Dim oldCulture As System.Globalization.CultureInfo = dataView.Table.Locale
            dataView.Table.Locale = New System.Globalization.CultureInfo("en-US")
            'sonstige Änderungen übernehmen ohne MegaByte Weise Viewstate für's RadGrid
            For Each p As String In HttpContext.Current.Request.Params                                               'Request Parameter itereieren
                If p.Contains(_grid.UniqueID) Then                                                                   'prüfen ob der der aktuelle Eintrag zum RadGrid gehört
                    Dim a = _grid.FindControl(p.Replace(_grid.UniqueID & "$", ""))                                   'das entsprechende Steuerelement finden
                    If a IsNot Nothing Then
                        If Assignments.Keys.Contains(a.ID) Then                                                      'prüfen ob das Steuerelement zu aktualisieren ist
                            Dim row = CType(a.Parent.NamingContainer, GridDataItem).ItemIndex                        'entsprechende Row des RadGrids ermitteln
                            dataView.Table.Rows(row).Item(Assignments(a.ID)) = HttpContext.Current.Request.Params(p) 'DataView-Feld mit dem entsprechenden Datum aktualisieren
                        End If
                    End If
                End If
            Next
            'Ende
            dataView.Table.Locale = oldCulture
        End Sub
    End Class

Anschließend kann man je nach Belieben bestimmte Werte im Grid, bzw. der dazugehörigen DataView aktualisieren, sodass beim Laden die Datenbindung an eine aktualisierte View erfolgt.
Warum ich in obigem Beispiel die Culture der DataView auf "en-US" setze und später wieder auf die eigentliche Kultur, erklärt sich im Artikel "CultureInfo: Chaos im .Net"

Beispiel:
Dim updateView As LCT.Tools.UpdateView = New LCT.Tools.UpdateView(RadGrid)
        updateView.Assignments.Add("GridEditItemID1", "DataViewColumnName1")
        updateView.Assignments.Add("GridEditItemID2", "DataViewColumnName2")
        updateView.Update(DataView)
So far...

Keine Kommentare:

Kommentar veröffentlichen

Feel free to comment...