With .NET interoperability it is possible to draw inside a NAV 2013 BLOB field. Consider the following snippet of code. “Picture Blob” is a BLOB field. We create a OutStream so we can write information into the blob. We must calc a BLOB field, even if its empty before getting the OutStream.
GenerateBitmap is a function that does the following:
- Creates a Bitmap instance (Size 50×50)
- Creates a Graphics instance on the bitmap
- Creates a SolidBrush in a specific color, in this case from a HTML color code.
- Draws an filled ellipse on the graphics in 0,0 -> 49,49 (bitmaps are 0-indexed)
- Saves the bitmap on the OutStream from our BLOB field.
All variables can be found in the System.Drawing Assembly.
This could be extended so we can draw on a existing BLOB field. So instead of creating a new Bitmap instance, we load the bitmap from an InStream.
And still saves to the OutStream. So you just have to create both the InStream and the OutStream from a BLOB.
One thing I have always missed in Navision/Dynamics NAV is BlobRef. We have RecordRef to access record, FieldRef to access fields (Not BLOB content) and KeyRef to access keys…
So how do we access BLOB content dynamic ?
What I would be 100% content with, are CREATEINSTREAM and CREATEOUTSTREAM methods on a FieldRef and be done with it, but a full blow BlobRef implementation would also work..
Or am I missing a way to do this ?
If you are in need of calling a DotNet method that is generic,usually written as class<T>.method<T>(parameters), you will discover that its not really possible with the standard way of calling a DotNet method with NAV2013.
You will get something like this, “The type of one or more arguments does not match the method’s parameter type” – And there are no way of getting rid of that with standard usage of DotNet variables.
But luckily, .NET has the reflection namespace that adds the possiblity to invoke a method through data. The following piece of codes calls the InserrAfterSelf method that is part of the OpenXML library.
First, we get the Type of the “ClonedRow” variable and get the MethodInfo of the method (variable “mi”). Then we need to call the “MakeGenericMethod” to create a MethodInfo that support a generic invoke. Parameters for MakeGenericMethod must be a array with the type of <T>, in my case the tableRow Type from OpenXML.
Now that we have a MethodInfo that supports generics, we just wee to create an array with the parameters for the actual call. Even though that with working with a method that only takes one parameter. (When programming in C#, the compiler will creates an array with one entry automatic, but not in NAV2013).
At last, we can invoke the generic method from NAV2013.
A fair warning at the end, Reflection is slow, so this is not the solution if you need to call the method a million times, if thats the case, consider to create a assembly and call that from NAV2013.