I'm doing some experimenting. I'd like to be able to take my DataTable Schema and loop through the fields and assign the corresponding Properties on my class. This way my code is generic and reusable.
Here is what I have so far:
ForEach clAs DataColumnIn dt.Columns
Dim colNameAsString = cl.ColumnName
Dim fAs System.Reflection.PropertyInfo =Me.GetType.GetProperty(colName)
f = ds.Tables(0).Rows(0)(cl.ColumnName)
Next
This obviously doesn't work.. but I know I HAVE to be getting close. How can I take "colName" and assign it's value to the Propery of the same name in the class, without hardcoding the name?
Now sure what properties of what you are setting, but here's some code i have filling an object called "Customers" with values from a DataReader (I made sure the SQL column names matched the property names:
Dim ThisReader As SQLDataReader
'blah blah, fill the DataReader with data and move the cursor to the first position with ThisReader.Read()
Dim csAs Customers =New Customers
Dim prAs System.Reflection.PropertyInfo()
pr = cs.GetType.GetProperties
ForEach piAs System.Reflection.PropertyInfoIn pr
pi.SetValue(cs,ThisReader.Item(pi.Name).ToString(),Nothing)
Next
BE AWARE!!!! That the ".SetValues" 2nd parameter, then actual value you are trying to pass in, is strongly typed and will crash if its not properly cast... in the stripped down example above, i am just assuming that all the properties are strings
It's
f.SetValue (ClassInstanceHere, "new value here", nothing)
So
f.SetValue(Me, ds.Tables(0).Rows(0)(cl.ColumnName), nothing)
You might have to cast ds.Tables... to a string, dunno.
Thanks... I'll try this in the morning when I am back at my PC.. I think it was the casting that killed me. My properties are declared only as "Object" to make them generic. I cast the values (or am trying to) when I write them to the DB after validating against an XSD.
Curt_C wrote:
Thanks... I'll try this in the morning when I am back at my PC.. I think it was the casting that killed me. My properties are declared only as "Object" to make them generic. I cast the values (or am trying to) when I write them to the DB after validating against an XSD.
h
If your properties are Object then you'll probably need to cast the value (ds.Tables(0).Rows(0)(cl.ColumnName)) to Object also.
Here's a sample of property/field setting using reflection that I'm using to process attribute key=value pairs from xml nodes. Note the use of the SetValue method and perhaps most importantly, using reflection to obtain the associated type converter for the property/field that is being set. It also handled the setting of complex properties such as "Style-Font-Size" by using GetValue to obtain references to parent property(ies):
'Set the sub/complex properties of the ParentProperty with the attributes attached to'the supplied Node. This is most appropriately used for attributes such as'Font-Bold, Font-Size, etc. Public Shared Sub SetSubProperties(ByVal Container As Object, ByVal ParentPropertyName As String, ByVal Node As XmlNode) Dim Attributes As XmlAttributeCollection = Node.Attributes For Each Attribute As XmlAttribute In Attributes Dim MethInfo As MethodInfo = Nothing Dim FldInfo As FieldInfo = Nothing Dim PropInfo As PropertyInfo = Nothing Dim FullPropertyName As String = ParentPropertyName & "." & Attribute.Name.Replace("-"c, "."c) Dim obj As Object = Container Dim objType As Type = obj.GetType Dim idx1 As Integer = 0 Dim names As String() = FullPropertyName.Split("."c) Dim name As String Do While idx1 <= names.Length - 1 name = names(idx1) Dim MbrInfo As MemberInfo() = objType.GetMember(name) ', BindingFlags.GetProperty Or BindingFlags.GetField) If MbrInfo Is Nothing OrElse MbrInfo.Length = 0 Then objType = Nothing Exit Do End If If MbrInfo(0).MemberType = MemberTypes.Property Then PropInfo = CType(MbrInfo(0), PropertyInfo) objType = PropInfo.PropertyType If idx1 < names.Length - 1 Then MethInfo = PropInfo.GetGetMethod obj = MethInfo.Invoke(obj, Nothing) Else MethInfo = PropInfo.GetSetMethod End If ElseIf MbrInfo(0).MemberType = MemberTypes.Field Then FldInfo = CType(MbrInfo(0), FieldInfo) objType = FldInfo.FieldType obj = FldInfo.GetValue(obj) End If idx1 += 1 Loop If Not objType Is Nothing Then Dim SubPropertyValue As Object = Attribute.Value Dim SubPropertyConverter As TypeConverter = TypeDescriptor.GetConverter(objType) Dim SubPropertyValueObject As Object = SubPropertyConverter.ConvertFrom(SubPropertyValue) If Not MethInfo Is Nothing Then Dim objArray2 As Object() = New Object() {SubPropertyValueObject} Dim objArray1 As Object() = objArray2 MethInfo.Invoke(obj, objArray1) Else If Not FldInfo Is Nothing Then FldInfo.SetValue(obj, SubPropertyValue) End If End If End If Next End Sub
Aidy wrote:
If your properties are Object then you'll probably need to cast the value (ds.Tables(0).Rows(0)(cl.ColumnName)) to Object also.
that wouldnt be necessary as "ds.Tables(0).Rows(0)(cl.ColumnName)" will already be of type "Object"
Hmmm... it was tossing some casting warnings if I remember right. I'll try again inthe morning and see what I can do though.
Thanks again
MorningZ wrote:
ForEach piAs System.Reflection.PropertyInfoIn pr
pi.SetValue(cs,ThisReader.Item(pi.Name).ToString(),Nothing)
Next
This is exactly what I needed. Thanks. I had
pi.SetValue(pi.Name, blah, blah)
It never occured to me to assign it back to "Me" (the function is in my class).
Thanks again...
Curt_C wrote:
It never occured to me to assign it back to "Me" (the function is in my class).
Despite me posting that 3 times, once even on this thread?
Aidy wrote:
Curt_C wrote:
It never occured to me to assign it back to "Me" (the function is in my class).Despite me posting that 3 times, once even on this thread?
Thanks to you as well... It wasn't till this morning that I got a chance to try it.
0 comments:
Post a Comment