Hallo,
ich arbeite mit einem typisierten DataSet und möchte diesem eine berechnete Spalte hinzufügen. Dazu möchte ich jedoch nicht die Expression-Eigenschaft verwenden, sondern richtigen Code schreiben können. Ausserdem soll es sich dabei um eine "vollwertige" DataColumn handeln, die sich beispielsweise per DataBinding filtern, sortieren und darstellen lässt (-> das hinzufügen einer public readonly property zur entsprechenden DataRow-Klasse wird also nicht genügen...).
Folgendes Codebeispiel zeigt meine aktuelle Lösung, mit der ich allerdings noch nicht ganz zufrieden bin. Das Beispiel erzeugt in der Tabelle dtPerson die berechnete Spalte FullName:
----------------------------------------------
Partial Class dsData
Partial Class dtPerson
Private FullNameColumn As DataColumn
Public ReadOnly Property FullName() As DataColumn
Get
Return FullNameColumn
End Get
End Property
Private Sub dtPersonDataTable_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Initialized
FullNameColumn = New System.Data.DataColumn("FullName", GetType(String), Nothing, System.Data.MappingType.Element)
MyBase.Columns.Add(FullNameColumn)
End Sub
' Die Spalte kann nun irgendwie berechnet werden. In diesem Fall werden die Change-Events
' von zwei anderen Spalten abgefangen und die FullName Spalte daraus berechnet:
Private Sub dtPersonDataTable_ColumnChanged(ByVal sender As Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles Me.ColumnChanged
Select Case e.Column.ColumnName
Case Me.FirstNameColumn.ColumnName
CType(e.Row, dtPersonRow).Item(FullNameColumn.ColumnName) = CType(e.Row, dtPersonRow).FirstName & " " & CType(e.Row, dtPersonRow).LastName
Case Me.LastNameColumn.ColumnName
CType(e.Row, dtPersonRow).Item(FullNameColumn.ColumnName) = CType(e.Row, dtPersonRow).FirstName & " " & CType(e.Row, dtPersonRow).LastName
End Select
End Sub
End Class
End Class
----------------------------------------------
Mit dieser Lösung habe ich nun folgende Probleme:
1.) Die neue Spalte ist dem Designer nicht bekannt. Sie muss also per Code gebunden werden.
2.) Ich lade und speichere das DataSet mit ReadXml bzw. WriteXml. Beim speichern wird nun aber auch die FullName-Spalte geschrieben (was dazu führt das die Daten nicht mehr mit dem Schema übereinstimmen, wenn ich das Schema ebenfalls schreibe).
Gibt es Attribute die diese Probleme lösen? (z.B. ein Attribut welches dem Designer mittteilt dass die Spalte aufzulisten ist?)
Oder hat jemand einen anderen, besseren Ansatz?
Vielen Dank schon mal für eure Hilfe.
Robert Hegner
ich arbeite mit einem typisierten DataSet und möchte diesem eine berechnete Spalte hinzufügen. Dazu möchte ich jedoch nicht die Expression-Eigenschaft verwenden, sondern richtigen Code schreiben können. Ausserdem soll es sich dabei um eine "vollwertige" DataColumn handeln, die sich beispielsweise per DataBinding filtern, sortieren und darstellen lässt (-> das hinzufügen einer public readonly property zur entsprechenden DataRow-Klasse wird also nicht genügen...).
Folgendes Codebeispiel zeigt meine aktuelle Lösung, mit der ich allerdings noch nicht ganz zufrieden bin. Das Beispiel erzeugt in der Tabelle dtPerson die berechnete Spalte FullName:
----------------------------------------------
Partial Class dsData
Partial Class dtPerson
Private FullNameColumn As DataColumn
Public ReadOnly Property FullName() As DataColumn
Get
Return FullNameColumn
End Get
End Property
Private Sub dtPersonDataTable_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Initialized
FullNameColumn = New System.Data.DataColumn("FullName", GetType(String), Nothing, System.Data.MappingType.Element)
MyBase.Columns.Add(FullNameColumn)
End Sub
' Die Spalte kann nun irgendwie berechnet werden. In diesem Fall werden die Change-Events
' von zwei anderen Spalten abgefangen und die FullName Spalte daraus berechnet:
Private Sub dtPersonDataTable_ColumnChanged(ByVal sender As Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles Me.ColumnChanged
Select Case e.Column.ColumnName
Case Me.FirstNameColumn.ColumnName
CType(e.Row, dtPersonRow).Item(FullNameColumn.ColumnName) = CType(e.Row, dtPersonRow).FirstName & " " & CType(e.Row, dtPersonRow).LastName
Case Me.LastNameColumn.ColumnName
CType(e.Row, dtPersonRow).Item(FullNameColumn.ColumnName) = CType(e.Row, dtPersonRow).FirstName & " " & CType(e.Row, dtPersonRow).LastName
End Select
End Sub
End Class
End Class
----------------------------------------------
Mit dieser Lösung habe ich nun folgende Probleme:
1.) Die neue Spalte ist dem Designer nicht bekannt. Sie muss also per Code gebunden werden.
2.) Ich lade und speichere das DataSet mit ReadXml bzw. WriteXml. Beim speichern wird nun aber auch die FullName-Spalte geschrieben (was dazu führt das die Daten nicht mehr mit dem Schema übereinstimmen, wenn ich das Schema ebenfalls schreibe).
Gibt es Attribute die diese Probleme lösen? (z.B. ein Attribut welches dem Designer mittteilt dass die Spalte aufzulisten ist?)
Oder hat jemand einen anderen, besseren Ansatz?
Vielen Dank schon mal für eure Hilfe.
Robert Hegner