By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,493 Members | 901 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,493 IT Pros & Developers. It's quick & easy.

Create an object at runtime

P: n/a
I have a DataTable with three string columns, "Value", "Format" and "Type"

However, some of the rows contain numbers and dates in the Value field. So
I would like to be able to format the output based on the format specifier
in the Format field. The problem is, since the Value field is a string, it
doesnt properly "format".

So I need to convert to an object of the type specified by "Type"...ok, so
Activator.CreateInstance() BUT the problem is, the constructors dont take a
string argument.

So how do I create a new object of the specified type without knowing what
arguments it will need? There are no empty constructors that I can find.

I am mostly using DateTime, Single, Integer and String values as my "Type"

My weak attempt so far is shown below...any help is greatly appreciated.
Thanks

Dave Taylor

dv = CType(source.List, DataView)

drv = dv(rowNum)

szF = drv("Format")

szT = drv("Type")

szV = drv("Value")

'Convert the string to the appropriate type

If (szF <> "") Then

t = Type.GetType(szT)

v = Activator.CreateInstance(t) '**Error occurs here because of no 'empty
constructors' available

Try

v = szV

szV = Microsoft.VisualBasic.Format(v, szF)

Catch ex As InvalidCastException

'Ignore, just output the unformatted data if there is an error converting

End Try

End If

Nov 20 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Cor
Hi Dave,

Can you show the code with what you construct your datatable.

I do not how your sample deals with that datatable.

Cor
Nov 20 '05 #2

P: n/a
Cor,

The code I attached is placed in the Paint method of a
DataGridTextboxColumn-derived class. The DataTable and associated DataView
objects work just fine.

The problem I'm having is creating a new object at runtime given only a
string containing its type and no arguments for its constructor. So
basically, if the Type field contains "DateTime" or "System.DateTime" I want
to create a new DateTime object. The Activator.CreateInstance is supposed
to do this, however, it seems to require arguments specific to each type,
else it throws an exception. My idea was to create an empty object of the
specified type and then use implicit conversion to get the value from my
"Value" string.

regards,
Dave

"Cor" <no*@non.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
Hi Dave,

Can you show the code with what you construct your datatable.

I do not how your sample deals with that datatable.

Cor

Nov 20 '05 #3

P: n/a
Cor
Hi Dave,

Where has that information to be.

In other words, is it a binded datagrid, is it back to the dataset.

That makes it difficult to see what you want.

I think I can understand the problem, but not the solution.

With a bounded datagrid, the "format" and "parse" events should work.
If not it seems to me a simple test of the value to know what has to be your
format.

But that is just from the information I got from you.

Because I do not understand why you needs the method you took.

Cor
Nov 20 '05 #4

P: n/a
"Dave Taylor" <no*********@processeng.com> schrieb
Cor,

The code I attached is placed in the Paint method of a
DataGridTextboxColumn-derived class. The DataTable and associated
DataView objects work just fine.

The problem I'm having is creating a new object at runtime given only
a string containing its type and no arguments for its constructor.
So basically, if the Type field contains "DateTime" or
"System.DateTime" I want to create a new DateTime object. The
Activator.CreateInstance is supposed to do this, however, it seems to
require arguments specific to each type, else it throws an exception.
My idea was to create an empty object of the specified type and then
use implicit conversion to get the value from my
"Value" string.


I think the problem is that you don't actually want to create a new object
and fill it by a value afterwards. You just want to convert a string to a
variable data type. So IMO the question is which conversion functions are
there and how can they be called dynamically? I'd create a new Sytem.Type
object depending on the String "System.DateTime" (or whatever). Then invoke
the Type object's parse method using reflection and passing the value
string. Afterwards call the ToString method and pass the format string. HTH.
--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #5

P: n/a
Armin,

Thanks for the reply. The Parse() method was exactly what I needed...my
code now looks like this and works fine. Thanks again.
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics,
ByVal bounds As System.Drawing.Rectangle, ByVal source As
System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal
backBrush As System.Drawing.Brush, ByVal foreBrush As System.Drawing.Brush,
ByVal alignToRight As Boolean)

Dim drv As DataRowView, dv As DataView

Dim v As Object, szV As String, szF As String, szT As String

Dim rect As Rectangle

dv = CType(source.List, DataView)

drv = dv(rowNum)

szF = drv("Format")

szT = drv("Type")

szV = drv("Value")

If InStr(szT, ".") = 0 Then szT = "System." & szT

'Convert the string to the appropriate type

If (szF <> "") Then

Try

v = Activator.CreateInstance(Type.GetType(szT))

v = v.Parse(szV)

szV = Microsoft.VisualBasic.Format(v, szF)

Catch ex As InvalidCastException

'Ignore just output the unformatted data if there is an error converting

End Try

End If

rect = bounds

g.FillRectangle(backBrush, rect)

rect.Offset(0, 2)

rect.Height -= 2

g.DrawString(szV, Me.DataGridTableStyle.DataGrid.Font, foreBrush,
RectangleF.FromLTRB(rect.X, rect.Y, rect.Right, rect.Bottom))

If _bOwnerDraw Then _ctl.Invalidate()

End Sub

"Armin Zingler" <az*******@freenet.de> wrote in message
news:e$**************@TK2MSFTNGP09.phx.gbl...
"Dave Taylor" <no*********@processeng.com> schrieb
Cor,

The code I attached is placed in the Paint method of a
DataGridTextboxColumn-derived class. The DataTable and associated
DataView objects work just fine.

The problem I'm having is creating a new object at runtime given only
a string containing its type and no arguments for its constructor.
So basically, if the Type field contains "DateTime" or
"System.DateTime" I want to create a new DateTime object. The
Activator.CreateInstance is supposed to do this, however, it seems to
require arguments specific to each type, else it throws an exception.
My idea was to create an empty object of the specified type and then
use implicit conversion to get the value from my
"Value" string.
I think the problem is that you don't actually want to create a new object
and fill it by a value afterwards. You just want to convert a string to a
variable data type. So IMO the question is which conversion functions are
there and how can they be called dynamically? I'd create a new Sytem.Type
object depending on the String "System.DateTime" (or whatever). Then

invoke the Type object's parse method using reflection and passing the value
string. Afterwards call the ToString method and pass the format string. HTH.

--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #6

P: n/a
"Dave Taylor" <no*********@processeng.com> schrieb
Armin,

Thanks for the reply. The Parse() method was exactly what I
needed...my code now looks like this and works fine. Thanks
again.


Some comments:
- I'd strongly recommend to enable Option Strict in the project properties.
You have to change the code like this:

szF = drv("Format").ToString
szT = drv("Type").ToString
szV = drv("Value").ToString

- The brackets around the expression with the If statement is superfluous:
If szF <> "" Then
Even better because faster:
If szf.Length > 0 Then

- I'd also use expressive names. szF, szT, szV is not very intuitive

- What I meant was that you do not need to create an instance using
activator.createinstance. Here a modified example (no intuitive names...):

Dim szV As String, szF As String, szT As String
Dim Result As String
Dim t As Type
Dim o As Object

szF = "dd.MM.yyyy"
szT = "System.DateTime"
szV = "1/1/2004"

Try
t = Type.GetType(szT)
o = t.InvokeMember( _
"Parse", _
Reflection.BindingFlags.Static _
Or Reflection.BindingFlags.InvokeMethod _
Or Reflection.BindingFlags.Public, _
Nothing, Nothing, New Object() {szV} _
)
Result = t.InvokeMember( _
"ToString", Reflection.BindingFlags.Instance _
Or Reflection.BindingFlags.InvokeMethod _
Or Reflection.BindingFlags.Public, _
Nothing, o, New Object() {szF} _
).ToString
Catch ex As InvalidCastException
'Ignore just output the unformatted data if there is an error converting
End Try
--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #7

P: n/a
Armin,

Thanks! I didnt quite get the not using CreateInstance part in your first
post, although using it worked as well. The InvokeMember works nicely too.

Thanks again
Dave
"Armin Zingler" <az*******@freenet.de> wrote in message
news:uH**************@TK2MSFTNGP12.phx.gbl...
"Dave Taylor" <no*********@processeng.com> schrieb
Armin,

Thanks for the reply. The Parse() method was exactly what I
needed...my code now looks like this and works fine. Thanks
again.

Some comments:
- I'd strongly recommend to enable Option Strict in the project

properties. You have to change the code like this:

szF = drv("Format").ToString
szT = drv("Type").ToString
szV = drv("Value").ToString

- The brackets around the expression with the If statement is superfluous:
If szF <> "" Then
Even better because faster:
If szf.Length > 0 Then

- I'd also use expressive names. szF, szT, szV is not very intuitive

- What I meant was that you do not need to create an instance using
activator.createinstance. Here a modified example (no intuitive names...):

Dim szV As String, szF As String, szT As String
Dim Result As String
Dim t As Type
Dim o As Object

szF = "dd.MM.yyyy"
szT = "System.DateTime"
szV = "1/1/2004"

Try
t = Type.GetType(szT)
o = t.InvokeMember( _
"Parse", _
Reflection.BindingFlags.Static _
Or Reflection.BindingFlags.InvokeMethod _
Or Reflection.BindingFlags.Public, _
Nothing, Nothing, New Object() {szV} _
)
Result = t.InvokeMember( _
"ToString", Reflection.BindingFlags.Instance _
Or Reflection.BindingFlags.InvokeMethod _
Or Reflection.BindingFlags.Public, _
Nothing, o, New Object() {szF} _
).ToString
Catch ex As InvalidCastException
'Ignore just output the unformatted data if there is an error converting End Try
--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.